3

たまに楽観的ロック例外が発生するシステムがあります。コードでこれを回避しましたが、JPA 2 を見ていると、これを処理するための注釈 (@Version) があることがわかります。
私たちが抱えている問題は、1 つのテーブルで複数のトランザクションが動作しており、完全なテーブル ロックを使用すると、同じレコードに変更が加えられていなくても、楽観的ロック例外が発生することです。

JBoss 4.2 サーバーで休止状態を使用しており、データベースは MySQL または SQL Server のいずれかです。

代わりに @Version を使用するように変更した場合、これにより両方のデータベースで行ロックが強制されますか、それとも完全なテーブル ロックによって引き起こされる楽観的ロック例外が引き続き発生することを期待できますか?

編集:
実際に見られるのは、楽観的なロック エラーではなく、デッドロックです。

SQLServerException: トランザクションが別のプロセスとのロック リソースでデッドロックされ、デッドロックの犠牲者として選択されました。トランザクションを再実行します。

コードでこれを処理しますが、この場合に @Version が役立つかどうか疑問に思っていました。
少なくとも 1 つのケースでは、このデッドロックは、2 つのクライアントが独自のデータを操作しているテーブル ロックが原因でした。

4

2 に答える 2

1

重複の可能性:楽観的ロックと悲観的ロック

オプティミスティック ロックの例外は、ほとんどの場合、ステートフルな同時実行の問題です。例: 2 つのスレッドがまったく同じエンティティをロードし、オブジェクトを並行して変更してから保存します。トランザクション (テーブル ロックまたは行ロック) に関係なく、これが発生すると楽観的ロック例外が発生します (参照されている質問を参照)。

オプティミスティック ロックの例外が発生することにショックを受けました。@Versionこの場合、本当のRDBMS OCC エラーが発生している可能性がありますが、疑わしいと思います。最も可能性が高いのは、オブジェクト全体が行に差分されることです (指定しなかったため@Version)。この場合、行を変更すると楽観的ロック例外が発生します。仮定する必要がないように、質問に例外を追加してください。

于 2013-03-07T15:14:09.823 に答える
1

SQL ステートメントによって異なります。楽観的ロックは、トランザクションが何らかの理由で必要なリソースのロックを取得できなかった場合に発生します。表ロックまたは行ロックが原因である可能性があります。それは問題ではありません。

テーブル ロックを必要とする SQL クエリを実行している場合は、バージョン フィールドに問題があります。デフォルトでは、MS SQL Server は行ロックを使用しています。おそらく、小さなテーブルがあるか、主キーが欠落しているか、SQL Server がクエリでテーブル ロックを使用する理由が他にあります。

テーブル ロックを生成するクエリを調査し、それを微調整する必要があります。時折ロックが発生することを想定して、アプリケーションで対処する必要があります。

于 2013-03-07T14:57:44.610 に答える