概要とか
テーブルスキャンによるロック待ちの解決策はいくつかあります。
解決方法1 – 検索列にインデックスを張る
検索列にインデックスを張ってテーブルスキャンを回避すれば、この問題は発生しません。
CREATE INDEX IDX_TABLE_A_DATA1 ON TABLE_A(DATA1);
ロックするほうのトランザクションを実行してみます。
BEGIN TRANSACTION
SELECT * FROM TABLE_A WITH(XLOCK, ROWLOCK, HOLDLOCK, INDEX(IDX_TABLE_A_DATA1)) WHERE DATA1=0;
インデックスなしのときにロック待ちになっていたトランザクションを実行してみます。
BEGIN TRANSACTION
SELECT * FROM TABLE_A WITH(INDEX(IDX_TABLE_A_DATA1)) WHERE DATA1=2;
こうすると、普通に結果が返ってきます。
なお、ここで明示的にインデックスを使わせているのは、インデックスヒントがないと実行計画的にテーブルスキャンのほうを選択してしまうからです。
解決方法2 – READ_COMMITTED_SNAPSHOT を使う
書きかけ
解決方法3 – SNAPSHOT分離レベルを使う
書きかけ
SQLServer2008で確認…中。