【訂正】
以下の文章が間違っていたことがわかったので、ここで訂正してお詫びします。
SQLServer2005のSERIALIZABLEレベルでは、クエリによる「範囲ロック」を行うことが問題の真のメカニズムでした。
新しいバージョンのSQLSERVERでは、クエリ範囲に該当する範囲ロックがかけられます。
以前の古いSQLServer(7.0)ではSERIALIZABLEレベルでロックを取得するとテーブルロックがかかっていました。
しかし、これでは同時実行性の悪化を招きます。
そのために改善された仕様が、クエリ条件に含まれる範囲をロックするというものです。
つまり、
SELECT * FROM EMP WHERE ENAME LIKE '山本%'
とすれば、「山本%」に該当するデータを操作することは行えず、挿入も行えません。
bit列のカーディナリティーが低いために、
全テーブルロックのように見えたのは、間接的に正しいですが直接の原因ではなかったようです。
また、SQLSERVERにビットマップインデックスはありません。
まちがっておりました。
【問題の内容】
SqlServer2005を使っていて、行ロックを取ろうとしたところ
テーブルロックになってしまう現象が発生し原因を追究していった。
SqlServerで行ロックを取得する場合、以下のようにクエリを記述する。
『クエリ1』
SELECT*FROM EMP WITH(UPDLOCK,ROWLOCK) WHERE EMPNO = 1
今日、以下のようなクエリでテーブルロックのように見えていた。
『クエリ2』
SELECT*FROM EMP WITH(UPDLOCK,ROWLOCK) WHERE ISDELETE = True