我已經閱讀了很多關於防止競爭狀態防止競爭條件,但通常在UPSERT情況下一個記錄。例如: Atomic UPSERT in SQL Server 2005橫跨多行
我有不同的要求,它是爲了防止跨多行的競爭條件。例如,假設我有以下表結構:
GiftCards:
GiftCardId int primary key not null,
OriginalAmount money not null
GiftCardTransactions:
TransactionId int primary key not null,
GiftCardId int (foreign key to GiftCards.GiftCardId),
Amount money not null
可能有多個進程插入GiftCardTransactions
,我需要防止插入如果SUM(GiftCardTransactions.Amount) + insertingAmount
會超出GiftCards.OriginalAmount
。
我知道我可以在GiftCardTransactions
上使用TABLOCKX
,但顯然這對大量交易是不可行的。另一種方法是增加一個GiftCards.RemainingAmount
列,然後我只需要鎖定一行(雖然鎖升級的可能性),但不幸的是,這不是在這個時候我的選擇(這將一直是最好的選擇嗎?) 。
,而不是試圖阻止在第一位置插入,也許答案是剛剛插入,然後選擇SUM(GiftCardTransactions.Amount)
,並在必要時回滾。這是一個邊緣情況,所以我不擔心不必要地使用PK值,等等。
所以問題是,沒有修改表結構和使用任何事務組合,隔離級別和提示,我怎麼能用最少量的鎖定實現這一目標?