2013-08-04 13 views
6

WITH(ROWLOCK)を使用してテーブルの行を更新しますが、 "sp_lock"を実行すると、ロックされたしたがって、トランザクションがコミットされる前に、他のトランザクションはテーブルの他の行を更新することができません。なぜ "WITH(ROWLOCK)"が効力を発揮しないのですか?更新ステートメントで "with(rowlock)"が使用されている間にテーブル全体がロックされる理由

私はROWLOCKで以下のクエリを使用しています:

DELETE FROM DefDatabaseSession WITH (ROWLOCK) WHERE ProcessName='test'; 

を同じ時間に他のトランザクションから同じテーブルの違い行の同じ削除操作を実行している私は、例外を

[取得していますSQLServer JDBCドライバ] [SQLServer]ロック要求のタイムアウト時間を超えました。ネストされた例外はjava.sql.SQLExceptionです。[newscale] [SQLServer JDBCドライバ] [SQLServer]ロック要求のタイムアウト時間を超過しました:com.newscale.bfw.udkernel.kernel.UdKernelException:udconfig.defdbsession.delete; SQLの未分類SQLException [DELETE FROM DefDatabaseSession WHERE ProcessName =?]; SQLステート[HY000];エラーコード[1222]。 [newscale] [SQLServer JDBCドライバ] [SQLServer]ロック要求のタイムアウト時間を超過しました。ネストされた例外はjava.sql.SQLExceptionです。[newscale] [SQLServer JDBCドライバ] [SQLServer]ロック要求のタイムアウト時間を超えました。

答えて

2

オプティマイザが行ロック・ヒント[WITH(ROWLOCK)がオプティマイザに問合せヒントを提供する]を無視している理由があります。これは、非常に多数の行に当たっている状況で発生します。そのようなシナリオでは、オプティマイザはテーブルをスキャンしてテーブルロックを取得するほうが実行可能であると判断します。このリンクに行くことができる詳細な議論については

http://social.msdn.microsoft.com/Forums/sqlserver/en-US/60238304-04e8-4f98-84d1-3ddf1ed786a9/why-the-entire-table-is-locked-while-with-rowlock-is-used-in-a-update-statement

0

私の推測では、あなたがProcessNameにインデックスを持っていないということですので、クエリは、フルテーブルスキャンを行う必要があり、したがって、すべての行が(読まれます可能な削除候補です)、すべての行をロックするよりもテーブル全体をロックするほうが効率的です。

CREATE INDEX DefDatabaseSession_ProcessName ON DefDatabaseSession(ProcessName); 

あなたは説明実行してクエリプランを見つけることができます:

EXPLAIN DELETE FROM DefDatabaseSession WITH (ROWLOCK) WHERE ProcessName='test'; 
+1

'EXPLAIN'がSQL Serverに存在しません

は、インデックスを定義してみます。計画を取得するには、「実際の実行計画を含める」ボタンを使用します。 – Alejandro

+0

私はProcessName列のインデックスを持っています。 – vani

+0

しかし、私は行ロックのみが必要です。他の行があると、他のスレッドが同時に削除することになります。 – vani

関連する問題