次のコードがあるとしましょう(ひどいことは無視してください):
BEGIN TRAN;
DECLARE @id int
SELECT @id = id + 1 FROM TableA;
UPDATE TableA SET id = @id; --TableA must have only one row, apparently!
COMMIT TRAN;
-- @id is returned to the client or used somewhere else
私の目には、これは並行性を適切に管理していません。トランザクションがあるからといって、更新ステートメントに到達する前に他の誰かがあなたと同じ値を読み取らないということにはなりません。
今、コードをそのままにしておきます(これは単一のステートメントとして処理するか、自動インクリメント/ ID列を使用することをお勧めします)並行性を適切に処理し、2つのクライアントが同じになる競合状態を防ぐ確実な方法id値?
WITH (UPDLOCK, HOLDLOCK)
SELECTにa を追加するとうまくいくと確信しています。SERIALIZABLEトランザクション分離レベルは、(それは誰にもTRANが終わるまで、あなたが何をしたか読むことを拒否したことから、同様の作業に思えるでしょうUPDATE:これは偽であることがわかりマーティンの答え)。本当?どちらも同等に機能しますか?一方が他方よりも優先されますか?
IDの更新よりも正当なもの、つまり更新が必要な読み取りに基づいた計算を行うことを想像してください。多数のテーブルが関係している可能性がありますが、そのうちのいくつかは書き込みを行い、他のテーブルは書き込みを行いません。ここでのベストプラクティスは何ですか?
この質問を書いた後、必要なテーブルのみをロックしているので、ロックヒントの方が優れていると思いますが、誰かの入力に感謝します。
PSそして、いいえ、私は最良の答えを知りません、そして、本当に、より良い理解を得たいです!:)
update
古いデータに基づいている可能性があるものを発行したりしないようにしますか?後者のrowversion
場合、列を使用して、更新される行が読み取られてから変更されていないかどうかを確認できます。