最大再試行回数に達するまでエンティティを複数回保存しようとするwhileループで解決しようとした並行性の問題があります。この問題を解決する他の方法があるかどうかについては話を避けたいです。他のStackoverflowの投稿もあります。 :)長い話:派生した列には一意の制約があり、衝突を避けるために増分し続ける数値部分が含まれています。ループでは、私は:
ループがステップ1に戻って選択しようとする場合を除いて、これらはすべて機能しているようです。
17:20:46,111 INFO [org.hibernate.engine.jdbc.batch.internal.AbstractBatchImpl] (http-localhost/127.0.0.1:8080-3) HHH000010: On release of batch it still contained JDBC statements
17:20:46,111 INFO [my.Class] (http-localhost/127.0.0.1:8080-3) MESSAGE="Failed to save to database. Will retry (retry count now at: 9) Exception: could not execute statement; SQL [n/a]; constraint [SCHEMA_NAME.UNIQUE_CONSTRAINT_NAME]; nested exception is org.hibernate.exception.ConstraintViolationException: could not execute statement"
そして、新しい例外がキャッチされます。一意制約違反を引き起こし、DataAccessException
をスローする最初のフラッシュは、エンティティマネージャのバッチをクリアしないようです。これに対処する適切な方法は何ですか? JPAでSpringを使用していますが、エンティティマネージャーに直接アクセスできません。必要な場合は注入できると思いますが、これはこの問題の痛みを伴う解決策です。
それを行うことはできません。何かをフラッシュして失敗すると例外がスローされると、トランザクションはロールバックとしてマークされます。つまり、例外をキャッチして続行することは問題ではなく、ロールバックが発生します。実際には、どの例外がスローされたかはまったく関係ありません。デフォルトでは、Springのトランザクションマネージャーは未チェック例外ごとにロールバックします。 @Transactional
アノテーションでnoRollbackFor
を明確に定義することにより、これを克服できます(アノテーションドライバートランザクションを使用している場合)
編集-トランザクションはおそらくデータベースレベルでロールバックとしてマークされるため、この制約違反の場合にも役立ちません。
私はこの質問に同じエラーが出るのを見つけました。私の場合、問題はトリガーと行ロックの奇妙な組み合わせが原因でした( テーブルにトリガーが追加されたときのPSQLExceptionとロックの問題 を参照)。ただし、このエラーが原因ではなく主なエラーの結果であることを発見するには、時間がかかりました。 Hibernateがセッションをフラッシュし、何らかの制約違反が発生すると、JDBC例外を受け取り、最終ブロックでabortBatch
の呼び出しを試みます。セッションにステートメントが残っている場合、Hibernateはこの警告を発しますが、実際のエラーは以前のどこかで検索する必要があります。