0

Java 永続性を使用する場合に、「再試行可能な」例外 (ロック待機タイムアウトなど) を再試行する正しい方法について、明確にする必要があります。たとえば、次のような疑似コードを使用します。

EntityTransaction tx = em.getTransaction();
tx.begin();
for (a bunch of objects) {
  em.persist(object);
}
tx.commit();

データベースにロックがある場合、em.persist 呼び出しで例外がスローされることがあります。それをtry/catchでラップして再試行できますか(明らかに、いくつかのカウントで)?それとも、tx.begin/commit 全体をラップしてやり直す必要がありますか?

どうも

4

3 に答える 3

1

データベースのデッドロックの回避策としてロック タイムアウトが存在しないと仮定すると、より簡単な解決策は、リクエストに対してより長いタイムアウトを使用することです。2 番目のタイムアウトを使用して最大回数Nまで再試行する代わりに、タイムアウトを秒に設定します。CN * (C + 1)

(デッドロックの回避策としてロック タイムアウトを使用している場合は、より大きな問題が発生します。C再試行してもトランザクションが失敗する可能性があるため、デッドロックの根本原因を修正することをお勧めします。通過します。)

于 2010-07-29T06:31:42.383 に答える
0

仕様に合わせてプログラミングしている場合、実際には EntityManager 全体を破棄して最初からやり直す必要があります。EM レベルで「再試行可能」であることが保証されている例外はありません。persist() メソッドから例外が発生した場合、永続化セッション全体が一貫性がない/不確定であると見なされます。

うまくいくこともあります。休止状態では、通常、楽観的ロック例外の後にゲインを試みることで逃げることができることを私は知っています。しかし、一般的に、entitymanager の例外をキャッチして回復し、同じ entitymanager を維持しようとすると、定義が不十分なベンダー固有の動作に依存しています。

詳細はこちら。

于 2010-07-29T03:47:45.143 に答える
0

EntityManager によってスローされた例外がトランザクションをロールバックのみとしてマークしない限り (LockTimeoutException はそのような例の 1 つですが、PessimisticLockException はそうではありません)、現在のトランザクションで物事を処理し続けることができます。

TX がロールバックのみとしてマークされた場合は、TX を救済し、TX 内でエラーが発生する前に試行したことをすべて再試行し、続行する必要があります。

JPA を使用して大量の処理を行う場合、DELETE または UPDATE jpql クエリの候補が得られる可能性があります。

于 2012-04-17T20:30:50.123 に答える