- ベストアンサー
※ 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も同じデータが取得されてしまいます。この現象の理由や共有ロックが可能となる条件について詳しい方の助言を求めています。
- みんなの回答 (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ということになります)
お礼
ご回答ありがとうございます。 やはり、MSDNの記述は見つかりませんよね。 MSDNに明確にかかれているのが理想なのですが。。。 恥ずかしながら、MSDNブログの存在を初めて知りました。 URLのブログエントリー読ませていただきましたが、 まさに、現状で起こっていることを物語っているように思えます。 jamshid6さんの回答にある通り、XLOCK,HOLDLOCK、または、TABLOCKXを検討することになりそうです。
補足
もう少し裏付けがあると助かりますので、 この現象に関連する記述を見かけた方いましたら、 ご回答お願いいたします。