最近,我们面临着一个问题,即要同时从多个客户端插入我们的sal服务器表之一。希望你们能帮助我们。
我们正在使用存储过程来进行交易。在该存储过程中,我们为每笔交易计算到目前为止的总销售额。如果总销售额小于设定的限制,则将允许该交易。否则,交易将被拒绝。
大多数时候都可以正常工作。但是,有时当多个客户端尝试完全同时执行事务时,由于两个事务都已完成,因此限制检查失败。
你们能建议我们如何一直有效地执行限制吗?有没有更好的方法可以做到这一点?
谢谢!
我认为声明式地执行此操作是不可能的。
如果保证所有插入都将通过存储过程,并且一旦插入后就不会更新SaleValue,则应执行以下操作(我组成了表名和列名,因为最初的问题中未提供这些名称)
DECLARE @SumSaleValue MONEY BEGIN TRAN SELECT @SumSaleValue = SUM(SaleValue) FROM dbo.Orders WITH (UPDLOCK, HOLDLOCK) WHERE TransactionId = @TransactionId IF @SumSaleValue > 1000 BEGIN RAISERROR('Cannot do insert as total would exceed order limit',16,1); ROLLBACK; RETURN; END /*Code for INSERT goes here*/ COMMIT
所述HOLDLOCK给序列化的语义和锁定的整个范围相匹配的TransactionId和UPDLOCK锁定在相同范围从而减少死锁的危险防止两个并发事务。
HOLDLOCK
TransactionId
UPDLOCK
上的索引TransactionId,SaleValue将最好支持此查询。
TransactionId,SaleValue