2011-10-18 10 views
1

更新を行うSQL文があり、@@ROWCOUNTが0の場合は挿入されます。これは基本的にSQL 2008のMERGEです。私たちは、2つのスレッドが同時に更新に失敗する状況に遭遇しています。同じキーをテーブルに2回挿入しようとします。私たちは既定のトランザクション分離レベルのRead Committedを使用しています。レベルを反復可能な読み取りに変更するとこれが解決されるのでしょうか、またはこの作業を行うためにシリアライズ可能にする必要がありますか?ここにいくつかのコードがあります:TRANSACTION ISOLATION LEVEL REPEATABLE READでupsert問題を修正していますか?

SET TRANSACTION ISOLATION LEVEL REPEATABLE READ; 

BEGIN TRAN;            
UPDATE TableA 
SET Duration = @duration    
WHERE keyA = @ID 
AND keyB = @IDB; 

IF @@rowcount = 0 
BEGIN 

INSERT INTO TableA (keyA,keyB,Duration) 
VALUES (@ID,@IDB,@duration); 

END 
COMMIT TRAN; 

SET TRANSACTION ISOLATION LEVEL READ COMMITTED;"; 
+0

Read Committed Transaction Isolationレベルで読み込みが不正になることはありません。 Read Uncommittedを使用すると、ダーティリードしか取得できません。 –

+0

申し訳ありません。更新とインサートをアトミックにすることです。それらをどのように組み合わせるか – Ryan

答えて

1

SERIALIZABLEまで進んでください。

REPEATABLE READの場合、行が存在しない場合は、両方ともUPDATEステートメントを互いにブロックせずに並行して実行し、挿入を実行することができます。 SERIALIZABLEの下では、行があったはずの範囲がブロックされます。

ただし、隔離レベルをデフォルトのread committedのままにし、ユニークな制約をkeyA,keyBに設定することで、デュプリケートを挿入しようとするとエラーが発生して失敗することも考慮する必要があります。

関連する問題