• ベストアンサー
※ ChatGPTを利用し、要約された質問です(原文:排他ロックしたレコードが、別トランザクションから参照されてしまい困っています。)

SQL Server2000の排他ロックについて

このQ&Aのポイント
  • SQL Server2000を使用している場合、あるトランザクションで排他ロックをかけたレコードが他のトランザクションから共有ロックを使用し参照できてしまう状態が存在するのか疑問です。
  • 具体的な状況として、二つのトランザクションが存在し、それぞれが異なるユーザでコネクションを張っています。autoCommitはfalseに設定され、テーブルにはプライマリキーやインデックスがなく、レコードは10件です。分離レベルはREAD COMMITTEDです。
  • トランザクションAから「SELECT * FROM TEST_TABLE WITH(XLOCK)」を発行し、その後トランザクションBから「SELECT * FROM TEST_TABLE」を発行する場合、トランザクションBの検索はタイムアウトすると予想されますが、実際にはトランザクションBも同じデータが取得されてしまいます。この現象の理由や共有ロックが可能となる条件について詳しい方の助言を求めています。

質問者が選んだベストアンサー

  • ベストアンサー
  • jamshid6
  • ベストアンサー率88% (591/669)
回答No.1

私はロックヒントを殆ど使わないのですが、実際主キーのないテーブルで試してみるとそうなります。 プロファイラで見ても、ロックヒントのないSELECTがテーブルに対するインテント共有ロック以外取得していないように見えます (ちなみにREPEATABLE READでは行共有ロックを取得し、SERIALIZABLEではテーブル共有ロックを取得しますし、主キーのあるテーブルではキーレベルの共有ロックを取得しいくのでXLOCKでブロックできます)。 MSDNのどこにもそのような記述はないので、いろいろ探した結果、あるMSDNのブログで1つだけそれらしい記述のあるものを見つけました。 > SQL Server avoids acquiring read committed locks when it knows that no data has changed on a page. http://blogs.msdn.com/craigfr/archive/2007/04/25/read-committed-isolation-level.aspx この理解が正しいとすれば、「ユーザデータベースでは変更のマークのないページには共有ロックはかけない」となり、XLOCKだけではREAD COMMITTEDのSELECTは阻止できませんから、SERIALIZABLEで排他することが必要になります。 (つまりXLOCK,HOLDLOCK、または、TABLOCKXということになります)

sinjanki
質問者

お礼

ご回答ありがとうございます。 やはり、MSDNの記述は見つかりませんよね。 MSDNに明確にかかれているのが理想なのですが。。。 恥ずかしながら、MSDNブログの存在を初めて知りました。 URLのブログエントリー読ませていただきましたが、 まさに、現状で起こっていることを物語っているように思えます。 jamshid6さんの回答にある通り、XLOCK,HOLDLOCK、または、TABLOCKXを検討することになりそうです。

sinjanki
質問者

補足

もう少し裏付けがあると助かりますので、 この現象に関連する記述を見かけた方いましたら、 ご回答お願いいたします。

関連するQ&A