2010-11-19 67 views
0

好的,我試過搜索並沒有找到答案 - 我很好奇ROLLBACK是如何處理競爭條件的。例如:競爭條件更新信用列的修改 - 回滾時會發生什麼?

如果我有一個表(CompanyAccount),用於跟蹤公司有多少可用於購買的貸方(每家公司數據庫表中只有一行),並且可能存在多個用戶可以從單個公司帳戶減少信用額的公司,發生ROLLBACK時發生錯誤時會發生什麼情況?

例子:

假設:我已經寫了更新正確計算出「信貸」新的平衡,而不是猜測的新增信貸餘額是多少(即我們不會試圖告訴UPDATE語句什麼新的信貸餘額/價值就是我們說拿無論是在信用列和UPDATE語句)減去我的減量值...

這裏的更新語句是怎麼寫的一個例子:

UPDATE DBO 。公司賬戶 SET Credit = Credit - @DecrementAmount WHERE CompanyAccountId = @CompanyAccountId

如果「貸方」欄有10,000個貸方。用戶A導致減少4,000個積分,而用戶B導致減少1000個積分。出於某種原因,在用戶A的減量期間會觸發回滾(在TRANSACTION期間,有大約1/2打多個表,行中有行被INSERTED)。如果用戶A贏得比賽條件並且新餘額爲6,000(但尚未提交),則在應用回滾之前發生用戶B遞減時會發生什麼情況?餘額列是否從6,000變爲5,000,然後將ROLLBACK變爲10,000?

我不太清楚ROLLBACK如何處理這個問題。也許我過於簡單化了。有人可以告訴我,如果我誤解ROLLBACK將如何工作,或者如果有其他風險,我需要擔心這種風格。

感謝您的輸入。

回答

3

在你給出的例子中沒有問題。

第一個事務將有一個排它鎖定,意味着第二個事務不能修改該行,直到第一個事務提交或回滾之後。它將不得不等待(鎖定),直到鎖定被釋放。

如果您有多個語句,它會變得更復雜一些。您應該閱讀不同的隔離級別以及它們如何允許或防止「丟失更新」等現象。

+0

根據此鏈接(http://msdn.microsoft.com/en-us/library/ms378149.aspx)「如果兩個事務使用單個UPDATE語句更新行並且不基於之前檢索到的更新值,丟失的更新不會發生在提交讀取的默認隔離級別。「 – Skyguard 2010-11-22 15:26:47

+0

感謝您的評論/幫助 – Skyguard 2010-11-22 15:27:36

1

回滾是事務的一部分,鎖定將在回滾期間保留。 ACID中的* A * tomic。 直到所有鎖定被釋放,用戶B纔會啓動。

會發生什麼:

  • 用戶A鎖行
  • 用戶B將無法看到行,直到鎖被釋放
  • 用戶A回滾,釋放鎖,變化從來沒有發生過。
  • 用戶B看到行。-1000將導致9000

但是,如果用戶B已經讀取了餘額,那麼它在UPDATE時會出現不一致。這取決於你實際在做什麼以及按什麼順序,因此需要了解isolation levels(以及有關幻像和不可重複讀取的問題)

SERIALIZABLE或REPEATABLE READ的替代方案可以在事務模式中使用sp_getapplock到交易的信號量部分。