- - PR -
SQLServer2000の排他ロックタイミングについて
投稿者 | 投稿内容 | ||||||||
---|---|---|---|---|---|---|---|---|---|
|
投稿日時: 2006-08-08 17:10
予期せぬ排他ロックとは何を指していますか? | ||||||||
|
投稿日時: 2006-08-08 17:56
マージレプリケーションに関してはあまり詳しくないのですが…
分離レベルがREAD COMMITTEDの場合、Insert文とUpdate文は発行された時点で 対象となるレコードに排他ロックがかかります。 SQLServerでは、排他ロックはだいたい主キーに対してかかります。 排他ロックはトランザクションが終わるまで取得しつづけます。 今回の場合、 D端末BのトランザクションからSelect文を発行した際に、端末AがInsertした レコードの排他ロックに引っかかっているように見えます。 ただ、普通ブロッキングが発生しただけではデッドロックにはならないはずなので、 Eでタイムアウトが発生する理由がちょっと分かりません。 DのSelect文がテーブルに対して共有ロック(ないし排他ロック)をかけていると、 デッドロックが発生しますが… (マージレプリケーションのストアドなら整合性を保つ為にやりそう) 仮にDのSelectがテーブルに対してロックをかけていると、CのInsert後に端末Aの トランザクションを一度コミットしない限り、DのSelectはブロックされたままに なります。 私としては、CのInsert後に一度コミットしてしまって、新しいトランザクションで EのInsertを行うようにする方法しか思いつきません… #微妙な案しか出せませんでした…orz [ メッセージ編集済み 編集者: がんふぃーるど 編集日時 2006-08-08 18:06 ] | ||||||||
|
投稿日時: 2006-08-08 18:22
minminnana 様
がんふぃーるど 様 ご回答ありがとうございます。
D〜Eの現象です。
> 分離レベルがREAD COMMITTEDの場合、Insert文とUpdate文は発行された時点で > 対象となるレコードに排他ロックがかかります。 そうですね、SQLServerの標準レベルでもありますし、当方でも確認しております。 ただし、今回は分離レベルをRead Uncommittedで設定しておりますので、 同一トランザクション上では、排他ロックにならない筈なのです。 > D端末BのトランザクションからSelect文を発行した際に、端末AがInsertした > レコードの排他ロックに引っかかっているように見えます。 Enterprise Managerのロック状況でも、タイミングはご指摘どおりです。 > EのInsertを別トランザクションにできたりしませんか? 以前、Microsoftへ問合せした際の回答内に、 「トランザクションを出来る限り短くして下さい」との 見解がございました。 また、この現象が再現されるまでは、このテーブルαへ対して、 同一処理のトランザクションと、別処理におけるトランザクションの 両手法を用いてInsert処理を行っていましたが、 同一トランザクションにおいて、現象の再現が多発し、全ての処理を 別トランザクションへ統一した経由がございます。 ですので、ご指摘の程は、既に実現しております。 それにより解消はされたと認識していたのですが、 同一設定されている他の環境にて検証すると再現してしまいました。 もしかしたらSQLServer自体の設定なのかと、 基底部分から見直している次第です。 もし、お気づきの事がございましたら、ご指南いただきたく存じます。 宜しくお願い致します。 | ||||||||
|
投稿日時: 2006-08-08 19:15
>同一トランザクションにおいて、現象の再現が多発し、全ての処理を
>別トランザクションへ統一した経由がございます。 既に対策済みでしたか。そ、そりゃぁそうですよね(汗 >それにより解消はされたと認識していたのですが、 >同一設定されている他の環境にて検証すると再現してしまいました。 別の環境ですか、それはまたやっかいですね… 基本的にSQLServerのロックの挙動が環境によって変わるとは思えないので、 APの方のモジュールが古いとか… | ||||||||
|
投稿日時: 2006-08-08 19:49
がんふぃーるど 様
ご返答ありがとうございます。 > 既に対策済みでしたか。そ、そりゃぁそうですよね(汗 とんでもございません、恐縮です。 > APの方のモジュールが古いとか… モジュールのデグレードに関しましては、 VSSによるソース管理や、モジュールテスト後から大きな変更はないので 無いと考えております。 > 別の環境ですか、それはまたやっかいですね… > 基本的にSQLServerのロックの挙動が環境によって変わるとは思えないので、 私もそう考えております。 しかし、しいて申し上げますと、 マージレプリケーションは別コネクションにて実行されるので その為に、今回の現象の起因となっているのかもしれません。 お手数をおかけ致しまして申し訳ありません。 宜しくお願い致します。 | ||||||||
|
投稿日時: 2006-08-17 19:07
解決策ではないんですが...
Insert側のセッションの分離レベルを ReadUncommitted にしても, それは,読み取り側のセッションには関係ないので, Insert側で分離レベルを下げても無駄でしょうね... 分離レベルは,基本的には,読み取り側のレベルです。 ReadUncommitted の意味は,「未コミットの行も "読み" 取れる」 ReadCommitted の意味は,「コミットされた行だけ "読み" 取れる」 インデックスは二重化されているわけではないので, インデックスレベルで,分離レベルを実現できているわけではないです。 なので, デフォルトの分離レベルの場合,つまり,ReadCommitted の場合は, 読み取り時に,index scan や table scan になる場合では, スキャン時に,未コミットのものに引っかかってしまうような場合は, 読み取り側でシカケを入れれない限りは,難しいでしょうね... (もちろん,そのシカケがないか?と質問だと思いますが...) 本当は,ReadCommitted 分離レベルでの読み取りは, ファントムが現れてもいい筈なので, インデックスに排他ロックがかかったものの内で, 追加の行に排他がかかったものだけは,スキップしてもいい筈なんですが, 更新での排他ロックとの区別はないので, そんなことは,仕組み上,無理なんですよね... ロックは,waiterリストに並んだものがあると, そのリストの末端に加わるので, 同一トランザクション内でも待ちが生じます。 なので,読み取り側のセッションでの待ちが, 追加側のセッションに影響を与えることがあります。 例えば, 読み取り側で,ページレベルで S がかかった場合は, 書き込み側は,行レベルやキーレベルで X するには, ページレベルで,IX を獲得する必要があるために, すでに,S がかかったままになっていれば,リストに並びます。 |