11

問題

DB2(バージョン9.5)では、SQLステートメント

SELECT o.Id FROM Table1 o, Table2 x WHERE [...] FOR UPDATE WITH RR

エラーメッセージが表示されますSQLSTATE=42829(カーソルで指定されたテーブルは変更できないため、FOR UPDATE句は使用できません)。

追加情報

WITH RR分離レベルで実行しているため、を指定する必要がありますREAD_COMMITTEDが、同じクエリを実行している別のプロセスがある間、クエリをブロックする必要があります。

これまでの解決策...

代わりに次のようにクエリすると、次のようになります。

SELECT t.Id FROM Table t WHERE t.Id IN (
    SELECT o.Id FROM Table1 o, Table2 x WHERE [...]
) FOR UPDATE WITH RR

すべてが正常に動作します。

新しい問題

しかし、複数のプロセスがこのクエリを同時に実行すると、デッドロック例外が発生することがあります。

質問

FOR UPDATEデッドロックが発生する可能性のある場所を導入せずにクエリを作成する方法はありますか?

4

1 に答える 1

15

まず、分離レベルREAD_COMMITTEDを設定するために、を指定する必要はありません。WITH RRこれにより、分離レベルが発生するためですSERIALIZABLEWITH RS(読み取り安定性)を指定するだけで十分です。

FOR UPDATE WITH RSを内部選択に伝播するには、追加で指定する必要がありますUSE AND KEEP UPDATE LOCKS

したがって、完全なステートメントは次のようになります。

SELECT t.Id FROM Table t WHERE t.Id IN (
    SELECT o.Id FROM Table1 o, Table2 x WHERE [...]
) FOR UPDATE WITH RS USE AND KEEP UPDATE LOCKS

JDBCを介してDB2でいくつかのテストを行いましたが、デッドロックなしで機能しました。

于 2010-10-12T15:39:02.427 に答える