5

我们最近面临一个问题,即从多个客户端同时插入到我们的一个 sal 服务器表中。我希望你们能帮助我们度过难关。

我们正在使用存储过程来进行交易。在该存储过程中,对于每笔交易,我们计算到目前为止的总销售额。如果总销售额低于设定的限额,则允许交易。否则,交易将被拒绝。

它在大多数情况下都能正常工作。但是,有时当多个客户端试图同时进行事务时,限制检查会失败,因为两个事务都完成了。

你们能建议我们如何始终有效地执行限制吗?有没有更好的方法来做到这一点?

谢谢!

4

1 回答 1

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可序列化的语义并锁定匹配的整个范围,TransactionIdUPDLOCK防止两个并发事务锁定相同的范围,从而降低死锁的风险。

最好有一个索引TransactionId,SaleValue来支持这个查询。

于 2013-02-16T19:19:44.723 回答