我们最近面临一个问题,即同时从多个客户端插入一个sal服务器表。我希望你们能帮助我们。
我们正在使用存储过程来执行事务。在该存储过程中,对于每笔交易,我们计算到目前为止的总销售额。如果总销售额低于设定限额, 那么交易将被允许。否则,交易将被拒绝。
大部分时间都可以正常工作。但是,有时当多个客户端同时尝试完成交易时,限制检查失败,因为两个事务都完成了。
你们可以建议我们如何有效地执行限制吗?有没有更好的方法呢?
谢谢!
答案 0 :(得分:5)
我认为不可能以声明的方式做到这一点。
如果保证所有插入都经过存储过程并且插入后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
上的索引最适合支持此查询。