2017-05-03 39 views
2

Javaアプリケーション内では、SQL Serverステートメントを使用していくつかのプロセスを一時停止します。(UPDLOCK、ROWLOCK)はテーブル全体をロックします。1行しか選択されていません

これは、SQL文です:

SELECT * FROM MESSAGES WITH (UPDLOCK, ROWLOCK) 
WHERE MESSAGES.INTERNAL_ID IN ('6f53448f-1c47-4a58-8839-e126e81130f0'); 

実行から当然のIN句の変更でのUUIDを実行します。

この私たちがロックするために使用するJavaコード:

entityManager.createNativeQuery(sqlString).getResultList() 

上記のSQL文は1行しか返します。残念ながら、テーブル全体がロックされているようです。その結果、ブロックされていないか、一部のみがブロックされているにもかかわらず、すべてのプロセスがロックされます。

UPDLOCKを指定してもテーブル全体がロックされるのはなぜですか?


追加情報:

  • MESSAGES.INTERNAL_IDはNULL不可能であるNVARCHAR(255)です。 それ以外の場合は、列に制約はありません。
  • 隔離レベルはREAD_COMMITTEDです。
+0

「メッセージ」テーブルの定義を提供します(IDは主キーですか)。あなたのトランザクション分離レベルは何ですか? –

+0

@MikhailLobanov質問に必要な情報を追加しました。 –

答えて

1

これはあなたのMESSAGES.INTERNAL_IDがキーではないためです。行がロックされたら、それを読んで値をチェックすることはできません。この列に主キーを作成してみてください。それが不可能なら

、それにINDEXを作成し、クエリを書き直す:

SELECT MESSAGES.INTERNAL_ID FROM MESSAGES WITH (UPDLOCK, ROWLOCK) 
WHERE MESSAGES.INTERNAL_ID IN ('6f53448f-1c47-4a58-8839-e126e81130f0'); 

MSDNは言う:行レベルロックを取得

ロックROWLOCK、UPDLOCK、AND XLOCKヒント かもしれません実際のデータ行ではなく、インデックスキーに配置ロックを設定します。 の例では、表にノンクラスタード・インデックスがあり、ロック・ヒントを使用するSELECT文 がカバー索引によって処理される場合、 のデータ行ではなく、カバー索引の索引キーにロックが取得されます。ベーステーブル。

+0

ありがとうございます!私は現在、ロックのために主キーを使用しています。 –

+0

ちょうど別の質問: 'SELECT MESSAGES.ID'は重要な部分か' WHERE MESSAGES.ID'ですか? –

+0

主キーを作成する場合は重要ではありません。 PKは通常クラスタ化インデックスです(クラスタ化インデックスは常にカバーしています)。しかし、クラスタ化されていないインデックスを作成する場合は、select listに注意する必要があります。 –

関連する問題