5

最近、複数のクライアントからsalサーバーテーブルの1つに同時に挿入するという1つの問題に直面しています。皆さんが私たちを助けてくれることを願っています。

トランザクションを実行するためにストアドプロシージャを使用しています。そのストアドプロシージャでは、トランザクションごとに、これまでの総売上高を計算します。総売上高が設定された制限を下回る場合、トランザクションは許可されます。それ以外の場合、トランザクションは拒否されます。

ほとんどの場合、正常に動作します。ただし、複数のクライアントがトランザクションを正確に同時に実行しようとすると、両方のトランザクションが実行されるため、制限チェックが失敗することがあります。

制限を常に効果的に実施する方法を提案できますか?それを行うためのより良い方法はありますか?

ありがとう!

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シリアル化可能なセマンティクスを提供し、に一致する範囲全体をロックし、 2つの同時トランザクションが同じ範囲をロックするTransactionIdのをUPDLOCK防ぎ、デッドロックのリスクを軽減します。

TransactionId,SaleValueこのクエリをサポートするには、上のインデックスが最適です。

于 2013-02-16T19:19:44.723 に答える