0

PlayFramework1.2.4プロジェクトでバッチジョブのステートレスセッションを使用しています。

行の挿入と更新は非常にうまくいっていますが、例外が発生したときにどうすればよいかわかりません。これが私のコードです:

try{
      statelesssession.insert(someobject);
   }
catch(ConstraintViolationException e)  //It happens from time to time dont ask me why..
   {
      ??????transaction.rollback();????? THATS MY CONCERN
   }
finally{
      transaction.commit();
   }

私が知る必要があるのは、100回の挿入ごとにデータをコミットしているということです。つまり、56番目のレコードで制約違反が発生し、トランザクションがロールバックした場合、他の55個のレコードも失われるのでしょうか。

はいの場合、constraintviolationexceptionで何をする必要がありますか?または、これを回避するために1レコードごとにコミットする必要がありますか?

4

3 に答える 3

1

このタイプのユースケースでは、すべてのデータを100個のオブジェクトに分割し、これらのオブジェクトのサブジョブを起動する別のジョブがあります。

この場合、私にとって最善のことは、例外をスローすることです。次に、マスタージョブはこの例外を取得し、100個のオブジェクトすべてがロールバックされます。次に、マスタージョブはこれらのオブジェクトに対して別のモードに入り、オブジェクトごとにサブジョブを再起動できます。その場合、例外をスローしたものだけが保存されません。

これは、バッチの一般的な処理です。すべてが正常であれば、100個のオブジェクトごとにコミットするため、バッチは高速ですが、エラーが発生した場合は、単一のオブジェクトのコミットにフォールバックするため、失敗したオブジェクトを保存しません。

しかし、mericano1が言ったように、あなたの場合の正しい振る舞いはビジネスルールの問題です。

于 2012-08-31T06:29:17.137 に答える
1

ロールバックすると、トランザクション内の以前のすべてのレコードも失われます。制約の例外があるレコードのみを失いたい場合は、各バッチのレコードをリストに保持し、バッチが爆撃されたときに1つずつコミットするように切り替えて、その後バッチを続行できます。

于 2012-08-30T19:01:25.757 に答える
0

100回の挿入ごとにコミットすると、56回目の挿入後のロールバックでも、前の55回の挿入がすべて元に戻されます。

挿入するたびにコミットできますが、非常に多くの行を挿入するバッチでは低速であるため、お勧めしません。

解決策は、セーブポイントを使用することです。

セーブポイントの設定は比較的高速です。挿入するたびに実行できます。セーブポイントを設定してもデータベースにデータは書き込まれません(後でコミットする必要があります)が、ロールバックは最後のセーブポイントまでのみ実行されます。

したがって、この例では、100(または何でも)行ごとに(そして確かに最後の行の後に)コミットし、すべての行の後にセーブポイントを設定します。エラーが表示されてアクションをロールバックすると、エラーのある挿入のみが取り消され、他の挿入は変更されません。

説明については、たとえばjava.sql.Connection.setSavepoint、java.sql.Savepoint、またはここを参照してください。

于 2012-08-31T10:32:53.833 に答える