ロック後にレコードを更新するために、SQLサーバーのROWLOCKを理解しようとしていました。これが私の観察であり、ROWLOCKがテーブルまたはページロックのようなものであるかどうか、または正しく試していないかどうかを確認したいと思います。ROWLOCK は、テーブルまたはページではなく、行のみに対するロックである必要があります。
これが私が試したものです:
IDとNamerow_lock_temp_test
の2 つの列を持ち、PK やインデックスを持たない単純なテーブルを作成しました。ここで、2 つの異なるクライアントであるが同じ資格情報である SQL Server を開き、次のように一連のクエリを実行しようとしました。
クライアント 1:
1: BEGIN TRANSACTION;
2: update row_lock_temp_test set name = 'CC' where id = 2
3: COMMIT
クライアント 2:
1: BEGIN TRANSACTION;
2: update row_lock_temp_test set name= 'CC' where id = 2
3: COMMIT
C-1 でクエリ 1、2 を実行し、C-2 に移動して同じクエリを実行しました。両方のクライアントがクエリを実行し、トランザクションをコミットしました。すべて問題ありません。
次に、クエリを更新するために RowLock を追加しました。
C-1
1: BEGIN TRANSACTION;
2: update row_lock_temp_test WITH(rowlock) set name = 'CC' where id = 2
3: COMMIT
C-2
1: BEGIN TRANSACTION;
2: update row_lock_temp_test WITH(rowlock) set name = 'CC' where id = 2
3: COMMIT
ここで、C-1 でクエリ 1 と 2 を実行してから C-2 に移動し、同じ 2 つのクエリを実行しようとしましたが、行が C-1 によってロックされているため、クエリは期待どおりスタックし、それまでキューに入れておく必要があります。トランザクションは C-1 でコミットされます。C-1でトランザクションをコミットするとすぐに、C-2でクエリが実行され、C-2でもトランザクションをコミットしました。すべて良い。
ここでは、行 ID = 3 で同じ一連のクエリを実行する別のシナリオを試しました。
C-2
1: BEGIN TRANSACTION;
2: update row_lock_temp_test WITH(rowlock) set name = 'CC' where id = 3
3: COMMIT
C-1 で最初の 2 つのクエリを実行してから、C-2 の最初の 2 つのクエリを実行しました。両方のクライアントで行 ID が異なりますが、それでも C-2 のクエリがスタックしました。これは、id = 2 でクエリを更新しているときにページまたはテーブルがロックされたことを意味します。行ロックを予期していましたが、ページまたはテーブル ロックのようです。
また、xlock、HOLDLOCK、および UPDLOCK をさまざまな組み合わせで使用してみましたが、常にテーブルをロックしています。行のみをロックする可能性はありますか。
選択と挿入は期待どおりに機能しています。
前もって感謝します。