5

ロックを取得しようとしている SQL Server 2012 で遊んでいます。私が見たチュートリアルに基づいて、テーブルの排他ロックを取得して、トランザクションが終了するまで、他のクエリがそこから情報を読み取ることができないようにテストしようとしましたが、それは機能しません。ビデオでは機能していましたが、最初のウィンドウでのクエリは次のとおりです。</p>

use TSQL2012

BEGIN transaction

update tele with (TABLOCKX, holdlock) 
set cor = '12'

waitfor delay '00:05'
go

次に、2 番目のクエリ ウィンドウで、次のことを試しました。

select * from tele

理論的にはそれを防ぐ「排他的」ロックがあったはずですが、それはうまくいきました。なぜそれが起こっているのですか?私も試してみました

set transaction isolation level serializable on

また、遅延はありませんが、選択は常に成功します。何か案は?

4

1 に答える 1

3

これを 2 つの異なるテーブルで試してみましたが、見つけたものを簡単に再現できます。何が起こっているかは次のとおりです。

テーブルが更新される前に Sql-Server が SELECT クエリに行を返す場合、その時点で排他ロックと互換性のないロックがテレ テーブルに既に存在する可能性が非常に高くなります。たとえば、テーブルにすでにリーダー ロックが設定されている別のセッションがどこかにある場合、UPDATE ステートメントは LCK_M_X の WAIT_TYPE で SUSPENDED になります。リリースされました。すべてのロックは排他的なテーブル ロックと互換性がないため、他のセッションが何らかの種類のロックでテーブルにアクセスしている場合、更新ステートメントは中断されます。

SQL Management Studio の 3 番目のインスタンスで、サーバーを右クリックし、アクティビティ モニターを開きます。データベースをフィルタリングしてログインし、実験を再実行します。テーブルがアプリケーションで頻繁に使用されるものであり、UPDATE の前に SELECT が実行される場合、UPDATE で LCK_M_X WAIT_TYPE に気付くでしょう。

自分だけが知っている新しいテーブルを作成して、実験を再実行してみてください。それはうまくいくはずです。

于 2018-01-26T17:41:15.020 に答える