[解決済み] UPDLOCK、HOLDLOCKの混乱について
質問
の使用について調べているうちに テーブルヒント の使用について調べているときに、次の 2 つの質問に出くわしました。
両方の質問に対する回答では
(UPDLOCK, HOLDLOCK)
を使用すると、他のプロセスはそのテーブルのデータを読み取ることができなくなる、とありますが、私はこれを見ませんでした。 テストするために、私はテーブルを作成し、2 つの SSMS ウィンドウを立ち上げました。 最初のウィンドウから、さまざまなテーブルヒントを使用してテーブルから選択するトランザクションを実行しました。 トランザクションが実行されている間、2 番目のウィンドウからさまざまなステートメントを実行し、どれがブロックされるかを確認しました。
テスト テーブルです。
CREATE TABLE [dbo].[Test](
[ID] [int] IDENTITY(1,1) NOT NULL,
[Value] [nvarchar](50) NULL,
CONSTRAINT [PK_Test] PRIMARY KEY CLUSTERED
(
[ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
SSMSウィンドウから1.
BEGIN TRANSACTION
SELECT * FROM dbo.Test WITH (UPDLOCK, HOLDLOCK)
WAITFOR DELAY '00:00:10'
COMMIT TRANSACTION
SSMSウィンドウ2より(以下のいずれかを実行)。
SELECT * FROM dbo.Test
INSERT dbo.Test(Value) VALUES ('bar')
UPDATE dbo.Test SET Value = 'baz' WHERE Value = 'bar'
DELETE dbo.Test WHERE Value= 'baz'
Window 2で実行されるステートメントに対する異なるテーブルヒントの効果。
(UPDLOCK) (HOLDLOCK) (UPDLOCK, HOLDLOCK) (TABLOCKX)
---------------------------------------------------------------------------
SELECT not blocked not blocked not blocked blocked
INSERT not blocked blocked blocked blocked
UPDATE blocked blocked blocked blocked
DELETE blocked blocked blocked blocked
私はこれらの質問で与えられた答えを誤解していたのでしょうか、それとも私のテストに間違いがあったのでしょうか? もしそうでないなら、なぜ
(UPDLOCK, HOLDLOCK)
と比較して
(HOLDLOCK)
のみですか?
私が達成しようとしていることをさらに説明します。
あるテーブルから行を選択し、そのテーブルのデータが処理中に変更されないようにしたいのです。 私はそのデータを変更しないので、読み取りが行われるようにしたいと思います。
この回答
は明確に次のように言っています。
(UPDLOCK, HOLDLOCK)
は読み込みをブロックする(私が望むものではない)。 のコメントは
この答え
が暗示するのは
HOLDLOCK
であることを意味します。 テーブルヒントの効果をよりよく理解するために、そして、もし
UPDLOCK
が単独で私が望むことを行うかどうかを確認するために、私は上記の実験を行い、これらの答えと矛盾する結果を得ました。
現在、私が考えるに
(HOLDLOCK)
を使うべきだと考えていますが、間違いを犯したり、何かを見落としたりして、それが将来私を苦しめることにならないか心配なので、この質問をさせていただきました。
どのように解決するのですか?
なぜUPDLOCKはセレクトをブロックするのですか?その
ロック互換性マトリックス
を見ると、明らかに
N
のように、S/UとU/Sのコンテンションに対して
ノーコンフリクト
.
については ホールドロック のヒントについて、ドキュメントにはこう書かれています。
HOLDLOCK: SERIALIZABLEと同等です。詳細については、このトピックで後述する SERIALIZABLE を参照してください。
...
SERIALIZABLE: ... スキャンはSERIALIZABLE分離レベルで実行されているトランザクションと同じセマンティクスで実行されます...
となり トランザクションの分離レベル トピックでは、SERIALIZABLE の意味について説明しています。
他のトランザクションは、現在のトランザクションが完了するまで、そのトランザクションによって読み取られたデータを変更できません。 他のトランザクションは、現在のトランザクションが完了するまで、そのデータを変更することはできません。
他のトランザクションは、現在のトランザクションのステートメントによって読み取られたキーの範囲に入るようなキー値を持つ新しい行を挿入することはできません。 現在のトランザクションのステートメントによって読み取られたキーの範囲内にある のステートメントが読み取るキーの範囲に入るキー値を持つ新しい行を挿入することはできません。
したがって、あなたが見た動作は、製品のドキュメントによって完全に説明されます。
- UPDLOCK は同時実行の SELECT や INSERT をブロックしませんが、T1 によって選択された行のすべての UPDATE または DELETE をブロックします。
- HOLDLOCKはSERALIZABLEを意味するため、SELECTSは許可しますが、T1によって選択された行のUPDATEとDELETESはブロックします。 と同様に T1 によって選択された範囲での INSERT (これはテーブル全体であり、したがって は任意の を挿入します)。
-
(UPDLOCK, HOLDLOCK): あなたの実験は、上記のケースに加えて何がブロックされるかを示していません、すなわち
T2 の UPDLOCK を持つ別のトランザクション
:
SELECT * FROM dbo.Test WITH (UPDLOCK) WHERE ...
- TABLOCKX 説明の必要なし
本当の疑問は 何を達成しようとしているのか ? ロック セマンティクスを完全に 110% 理解していない状態でロック ヒントを使用することは、トラブルの元です...。
OP編集後。
<ブロッククオートあるテーブルから行を選択し、処理中にそのテーブルのデータが変更されないようにしたい。 テーブルのデータが変更されないようにしたいのですが。
より高いトランザクション分離レベルのいずれかを使用する必要があります。REPEATABLE READは読み込んだデータが変更されることを防ぎます。SERIALIZABLEは読み込んだデータが変更されることを防ぎます。 と 新しいデータが挿入されるのを防ぎます。トランザクション分離レベルを使用することは、クエリヒントの使用とは対照的に、正しいアプローチです。Kendra Little は に、分離レベルについて説明した素晴らしいポスターがあります。 .
関連
-
[解決済み] SQL Server xp_delete_file パラメータ
-
[解決済み] 等値演算で "SQL_Latin1_General_CP1_CI_AS" と "Latin1_General_CI_AS" の照合の競合を解決できない
-
[解決済み] TABLOCKとTABLOCKXの比較
-
[解決済み] 分散型トランザクションを開始できない
-
[解決済み] 関数内から実行できるのは、関数と一部の拡張ストアドプロシージャのみです。
-
[解決済み] NVARCHAR(MAX)の最大文字数を教えてください。[重複しています]。
-
[解決済み] SQL Serverのタイムスタンプ列をdatetime形式に変換する方法
-
[解決済み] SQL Serverは、ビュークエリでLEFT JOINをLEFT OUTER JOINに置き換えます。
-
[解決済み] データベース内の全テーブルのサイズを取得する
-
[解決済み] SET NOCOUNT ON 使用法
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】PRIMARY KEY制約に違反しました。オブジェクトに重複したキーを挿入できない
-
[解決済み] FOREIGN KEY制約で参照されているため、テーブルを切り捨てることができないのですか?
-
[解決済み] SQL Serverでシングルクォートを置換する
-
[解決済み] MS SQL Server 2005で行のSNoを自動的に設定する方法は?
-
[解決済み] SSIS - データ損失の可能性があるため、値を変換することはできません。
-
[解決済み] T-SQL XOR 演算子
-
[解決済み] SQLでテーブルの行数を数える
-
[解決済み] SQL ServerでRegExを使用する
-
[解決済み] SQL Server のストアドプロシージャを SQL Developer で実行するには?
-
[解決済み] SQL ServerでGROUP BYと一緒にDISTINCTを使用する