2つのセッションが1つのテーブルにアクセスするとき、異なる抽出条件に
なっているにも関わらず、そこでデットロックが発生することはないだろうか?
■状況
たとえば、テーブルのカラムが
ID
GROUP
NAME
AGE
となっていて、
セッション①
WHERE ID = 1
セッション②
WHERE ID = 2
などとアクセスする。
このとき、別のデータを取得しようとしているので、ぶつからないはずである。
■原因
いくつかあるのだが、以下のような場合である。
①ID、GROUPのカラムで複合一意キーを指定していたが、どちらか片方で
アクセスしていた。
②一意キー以外の条件でアクセスすると、関係ないレコードまでロックされる
(SQLSERVERは、勝手に広範囲をロックしてしまうようだ)
■対応策
①複合一意キーの場合は、その定義順序で、定義されているカラムを必ず指定すること
②
一意キー以外の条件でアクセスする場合、WITH (NOLOCK) オプションでまず
データを取得する。その後、取得結果をカーソルでまわしながら、一意キーで
再度SELECTする。
※ WITH (NOLOCK) オプションは、ROLLBACK時の影響があることから乱用は避けたい
このような対応で、ロック範囲は意図した通りとなり、デットロックは軽減される。
■参考
ロック範囲が意図した範囲か確認する方法として、以下がある。
「Management Studio」を2つ起動させておく。
①片方で、範囲外と思われるレコードをUPDATE
②もう片方で、確認したいSELECT文を流す( 調べたいWHERE句を指定して )
以上を実行してみて、固まる(ロック待ち)となれば、ぶつかっているし、
無事にSELECTできれば、ロック範囲は重なっていない。
0 件のコメント:
コメントを投稿