我们最近面临一个问题,即从多个客户端同时插入到我们的一个 sal 服务器表中。我希望你们能帮助我们度过难关。
我们正在使用存储过程来进行交易。在该存储过程中,对于每笔交易,我们计算到目前为止的总销售额。如果总销售额低于设定的限额,则允许交易。否则,交易将被拒绝。
它在大多数情况下都能正常工作。但是,有时当多个客户端试图同时进行事务时,限制检查会失败,因为两个事务都完成了。
你们能建议我们如何始终有效地执行限制吗?有没有更好的方法来做到这一点?
谢谢!
我们最近面临一个问题,即从多个客户端同时插入到我们的一个 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
防止两个并发事务锁定相同的范围,从而降低死锁的风险。
最好有一个索引TransactionId,SaleValue
来支持这个查询。