2016-02-29 3 views
5

SQL Serverの各SELECTステートメントは、共有ロックまたはキーロックのいずれかが配置されると考えています。しかし、それがトランザクションのときに同じタイプのロックを配置するのだろうか?共有キーまたはキーロックにより、他のプロセスが同じレコードを読み取ることができますか?例えばSQL Serverのトランザクション内でSELECTステートメントにどのような種類のロックが設定されているか

Iこの時点で、次のロジック

Begin Trans 
-- select data that is needed for the next 2 statements 
SELECT * FROM table1 where id = 1000; -- Assuming this returns 10, 20, 30 

insert data that was read from the first query 
INSERT INTO table2 (a,b,c) VALUES(10, 20, 30); 

-- update table 3 with data found in the first query 
UPDATE table3 
SET d = 10, 
    e = 20, 
    f = 30; 

COMMIT; 

は私のselect文はまだ共有やキーロックを作成するか、それが排他ロックにエスカレートれますか?他のトランザクションは、テーブル1からレコードを読み取ることができますか、他のトランザクションが選択できるようになる前に、自分のトランザクションがコミットされるまで、すべてのトランザクションは待機しますか?

アプリケーションでは、トランザクションの外でselect文を移動して、挿入/更新を1つのトランザクションに保持するためです。

答えて

7

SELECTは常に共有ロックを配置します - あなたはWITH (NOLOCK)ヒントを使用しない限り、(その後、何のロックが格納されることになりますREAD UNCOMMITTEDトランザクション分離レベル(同じもの)を使用するか、またはあなたが、具体的クエリヒントでそれを上書きしない限りWITH (XLOCK)またはWITH (UPDLOCK)のようになります。

共有ロックを使用すると、他の読み取りプロセスも共有ロックを取得してデータを読み取ることができますが、排他ロック(挿入、削除、更新操作)が取得されることはありません。

この場合、3行だけを選択すると、ロックエスカレーションが発生しません(1回のトランザクションで5,000を超えるロックが取得された場合にのみ発生します)。

トランザクション分離レベルに応じて、これらの共有ロックは異なる時間間隔で保持されます。 READ COMMITTED(デフォルトレベル)では、データが読み取られた直後にロックが解放され、REPEATABLE READまたはSERIALIZABLEレベルの場合、ロックはトランザクションがコミットまたはロールバックされるまで保持されます。

+0

この貴重な情報をありがとうございました。したがって、SQL Serverが任意のselectステートメントに対してデフォルトで 'Read Committed'を使用している場合です。トランザクションの外でSELECTクエリを分離しようとしたためではありません。 –

+0

@MikeA:いいえ、違いはありません - 共有ロックは、実際にはデータを読み取る*ためにちょっとだけ取得されます。あなたがそれらを読んでいる間にそれらを変える)、そしてそれらは再び解放されるでしょう - その取引の内側または外側 - 同じプロセス –

+0

あなたがこれに気付かない場合:READ COMMITTEDは常にロックしないことを選択します。ロックはコミットされていない変更が加えられたページでのみ行われます。あなたはXLOCKであったRCの下のテーブルを読むことができ、別のトランザクションによってTABLOCKされたテーブルを読むことができます。 (私はそれを試しました) – usr

関連する問題