レベルエンター山本大のブログ

面白いプログラミング教育を若い人たちに

BLOCKVROCKリファレンス目次はこちら

「訂正」【SQLSERVER2005】Bit列で、行ロックしたはずがテーブルロックになる

【訂正】
以下の文章が間違っていたことがわかったので、ここで訂正してお詫びします。

SQLServer2005のSERIALIZABLEレベルでは、クエリによる「範囲ロック」を行うことが問題の真のメカニズムでした。

新しいバージョンのSQLSERVERでは、クエリ範囲に該当する範囲ロックがかけられます。

以前の古いSQLServer(7.0)ではSERIALIZABLEレベルでロックを取得するとテーブルロックがかかっていました。
しかし、これでは同時実行性の悪化を招きます。
そのために改善された仕様が、クエリ条件に含まれる範囲をロックするというものです。

つまり、

SELECT * FROM EMP WHERE ENAME LIKE '山本%'

とすれば、「山本%」に該当するデータを操作することは行えず、挿入も行えません。


bit列のカーディナリティーが低いために、
全テーブルロックのように見えたのは、間接的に正しいですが直接の原因ではなかったようです。

また、SQLSERVERにビットマップインデックスはありません。
まちがっておりました。


【問題の内容】
SqlServer2005を使っていて、行ロックを取ろうとしたところ
テーブルロックになってしまう現象が発生し原因を追究していった。

SqlServerで行ロックを取得する場合、以下のようにクエリを記述する。

『クエリ1』

SELECTFROM EMP WITH(UPDLOCK,ROWLOCK)
WHERE EMPNO = 1

今日、以下のようなクエリでテーブルロックのように見えていた。

『クエリ2』

SELECTFROM EMP WITH(UPDLOCK,ROWLOCK)
WHERE ISDELETE = True