5

我正在寫一個同步軟件,它將在一個數據庫中進行所有更改並將它們同步到另一個數據庫。爲此我已在我的表T兩列:在這個UPDATE語句中是否有可能的競爭條件?

alter table T add LastUpdate rowversion, LastSync binary(8) not null default 0 

現在我可以很容易地選擇自上次同步已更改的所有行:

select * from T where LastUpdate > LastSync 

但是執行同步我應該後使兩個領域平等。但更新行也更新時間戳,所以我必須這樣做:

update T set [email protected]@DBTS+1 where [email protected] 

但我想知道 - 這將始終工作?如果我讀取@@DBTS的值,然後另一個用戶在我的行提交之前設法在某處插入/更新行,該怎麼辦?這是有風險的代碼嗎?如果是的話 - 它怎麼會變得更好?

+0

順便問一下SQL Server的版本和版本是什麼?是[更改數據捕獲](http://msdn.microsoft.com/zh-cn/library/bb522489.aspx)選項? – 2010-10-22 11:52:29

+0

@Martin Smith - 2008,我想。不確定客戶有什麼。 – 2010-10-22 13:37:15

+0

@馬丁史密斯 - 我檢查了更改數據捕獲,但這將是一個矯枉過正。一個簡單的時間戳就足夠了。我只需要知道哪些記錄仍然需要同步。我不需要完整的歷史。 – 2010-10-22 14:09:28

回答

-1

如果您在Serializable事務中運行此操作,則不會有其他讀/寫操作能夠影響這些表。作爲真正的數據可能不是一個好主意,在所有

RepeateableRead也可以做在同一個表中的工作...

+1

桌子 - 是的。但是'@@ DBTS'的價值呢?這不是存儲在任何表格! – 2010-10-22 11:07:27

+0

@Vilx如果在同步持續時間內使用獨佔表鎖,那麼假設「@@ DBTS」被另一個表中的事件增加後並不重要。 – 2010-10-22 11:13:30

+0

@Martin Smith - 但@@ DBTS是全球數據庫的全球性用戶。爲什麼不重要?如果我爲LastSync字段獲取了一個(較舊的)值,並且爲LastUpdate字段獲得了一個較新的值,那麼我的同步將被打破。 – 2010-10-22 11:25:51

4

存儲「LASTSYNC」。 嘗試將它存儲在沒有rowversion的另一個表中。這樣你避免了「更新行也更新時間戳」 - 問題。

你的同步軟件,那麼可以以這種方式工作:

  • 獲取從附加表的@LastSync值
  • 「選擇在T @ThisSync = MAX(LASTUPDATE)其中LASTUPDATE> @LastSync」
  • 「Select * from T where LastUpdate> @LastSync和LastUpdate < = @ThisSync」是您的同步行數
  • 將@ThisSync存儲爲附加表中新的「LastSync」。

在同步運行時修改的條目將具有比max()查詢更高的rowversion值。下次您的同步器被調用時,它們將被同步。

+0

這是一個想法。我會記住,萬一沒有更好的出現。 – 2010-10-22 11:49:37