0

リモートデータベース(MsSql)と複数のWindows/Webクライアントを持つ自動化プロジェクトがあります。クライアントアプリケーションは、テーブル上の適切な行をチェックして選択し、その行を操作するために予約済みとしてマークします。

  1. 別のクライアントが同じ行を選択する前に、値を簡単に取得して選択した行を更新するにはどうすればよいですか?そのためにどのようなオプションがありますか?
  2. TransactionScopeトランザクションブロック内で(異なるテーブルに対して)複数のselect-updateステートメントを実行したい場合、その目的で使用できますか?

編集:映画のチケットシステムを想像してみましょう(私のものはもう少し複雑です)。ユーザーは座席を選択してチケットを購入します。このユーザーの席を2分間予約して、購入に十分な時間を与えたいと思います。2分後、他のユーザーも利用できるようになります。行を更新する前に、selectクエリを実行して、最初の空いているシートを見つけます。私の質問は、同じユーザーのselectステートメントとupdateステートメントの間の少しの時間についてです。防止したい:User1のselectステートメントが実行され、その時点でUser1がシートを予約する前にUser2が同じselectを実行します。

4

2 に答える 2

2

ロックしてから実際のアクションを実行するまでの間にユーザー入力が必要なため、

update top (1) seats
set time_locked = getdate(), user_locked = <the site user>
output inserted.seat_id, inserted.time_locked, inserted.user_locked
where <your conditions> and time_locked is null

この場合、変更をすぐにコミットするため、これを行う前にトランザクションを開始しないでください。後で、行をロックするとすぐに、またはさらに後の時点で、トランジションを開くことができます。

トランザクションからそれを行う場合、他のプロセスはそのトランザクションをコミットするまで待機するため、同時実行性は得られません。次に表示されるのは、1つのプロセスが機能し、他のすべてのプロセスが待機していることです。

後でロックされた行に戻ったときに、time_lockedがまだnull以外であり、ロックしたユーザーが同じユーザーであることを確認します。

update seats
set totally_taken = 1
where
  seat_id = <remembered seat id>
  and time_locked = <remembered time_locked>
  and user_locked = <remembered user_locked>
于 2012-10-20T23:22:52.233 に答える
0

SQL Serverを使用している場合は、選択項目でROWLOCKを実行できます。

SELECT * FROM Orders WITH ROWLOCK WHERE Status ='Pending'

于 2012-10-20T23:10:55.700 に答える