我已经阅读了很多关于防止竞争状态防止竞争条件,但通常在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值,等等。
所以问题是,没有修改表结构和使用任何事务组合,隔离级别和提示,我怎么能用最少量的锁定实现这一目标?