2011-02-07 7 views
3

私は原子的に実行する必要がある一連のT-SQLクエリを持っています。 (以下を参照)...目的は、1人のユーザーが一度に1つの一意の行を検索し、他のユーザーが同じ行を同時に検索できないようにすることです。TABLOCKX対SERIALIZABLE

これまでのところ、私は2つの解決策を見てきました。 1)表ヒント(HOLDLOCK、TABLOCKX)及び2)トランザクション分離レベル(SERIALIZABLE)...

私の質問:

  1. どのオプションが良いですか?

  2. 他にも優れたソリューションがありますか?この場合

DECLARE @recordId int; 

SELECT @recordId = MIN([id]) 
FROM Exceptions 
WHERE [status] = 'READY'; 

UPDATE Exceptions 
SET [status] = 'PROCESSING', 
    [username] = @Username 
WHERE [id] = @recordId; 

SELECT * 
FROM Exceptions 
WHERE [id] = @recordId; 

答えて

7

  • HOLDLOCK = SERIALIZABLE =期間、並行処理
  • TABLOCKXが

排他テーブル・ロックを= 2つの概念は異なっていてどちらもあなたが望むことはしません。

avoid race conditionsにするには、ノンブロッキング(READPAST)排他(UPDLOCK)行レベル(ROWLOCK)ロックを強制する必要があります。また、OUTPUT節を使用して、アトミックになる単一のステートメントにすることもできます。これはうまくいきます。一般に

UPDATE 
    E 
SET 
    [status] = 'PROCESSING', [username] = @Username 
OUTPUT 
    INSERTED.* 
FROM 
    (
    SELECT TOP 1 id, [status], [username] 
    FROM Exceptions (ROWLOCK, READPAST, UPDLOCK) 
    WHERE [status] = 'READY' 
    ORDER BY id 
    ) E 

、ロックは3つの態様

  • 粒度=ロックされているもの=行、ページ、テーブル(PAGLOCK, ROWLOCK, TABLOCK
  • 分離レベル=ロック時間、並行性(HOLDLOCK, READCOMMITTED, REPEATABLEREAD, SERIALIZABLE
  • を有しますモード=共有/排他(UPDLOCK, XLOCK

  • あなたは典型的なキュー処理とどちらTABLOCKXを記述し、また、直列化可能であり、例えばNOLOCK, TABLOCKX
2

「組み合わせ」が必要であり、また彼らが実際に動作します。可能であれば何ができないのかということについて、deptディスカッションのためにUsing tables as Queuesに行くことをお勧めします。その要旨は次のとおりです。

  • 適切なクラスタ化キー(!重要)
  • 使用OUTPUT句
  • 使用READPAST
を選択
関連する問題