web-dev-qa-db-ja.com

Entitymanager.flush()VS EntityManager.getTransaction()。commit-私は何を好むべきですか?

データベースを更新するとき、私は何を好むべきですか?どちらの方法の長所と短所は何ですか、いつどちらを使用しますか?

public void disemployEmployee(Integer employeeId, Date endDate) {
    Employee employee = (Employee)em.find("Employee", employeeId);
    employee.getPeriod().setEndDate(endDate);
    em.flush();
}

public void disemployEmployee(Integer employeeId, Date endDate) {
    Employee employee = (Employee)em.find("Employee", employeeId);
    em.getTransaction().begin();
    employee.getPeriod().setEndDate(endDate);
    em.getTransaction().commit();
}
44
Rox

最初の例では、データの変更はフラッシュの発生後にデータベースに反映されますが、まだトランザクション中です。

ただし、2番目の例では、トランザクションをすぐにコミットしています。したがって、変更はデータベースに加えられ、トランザクションもそこで終了します。

フラッシュは、進行中のトランザクション間でデータを保持し、その後最終的に変更をコミットするのに役立つ場合があります。そのため、後でバッチ挿入/更新などの問題が発生した場合、以前の変更をロールバックすることもできます。

46
Nayan Wadekar

フラッシュとコミットのためにjavadocを読んで、フラッシュは使用のみwithinトランザクションのみであることを知っていますか?コミットはデータをコミットしますが(明らかに)、フラッシュします(コミットしません)。それらは明確です。持つべき「好み」はありません。最初の例は間違っており、フラッシュの呼び出しで例外が発生するはずです(TransactionRequiredException)

15
DataNucleus

どちらのコードサンプルも、DBに書き込まれるエンティティ状態を永続化またはマージしません。

EntityManager.flush()EnityManager.EntityTransaction.commit()を比較することは適切ではないと思います。

flush()はトランザクションコンテキストで囲む必要があり、(まれに)EntityTransaction.commit()がそれを行う場合、必要でない限り明示的に行う必要はありません。

このリンクを参照してください この状況でflush()(JPAインターフェース)を呼び出す必要がありますか?

このリンクを参照してください クエリが呼び出される前のJPAでのフラッシュに関する質問 flush()を使用するシナリオ

3

不足している部分は、flush()がコミットする準備ができるようにデータソースに追加するだけで、実際のIDを提供しますが、デフォルトでは永続化しないと思います。

したがって、commit()として機能するためにflush()が必要な場合は、EntityManagerでフラッシュモードをCommitに設定する必要があります。

void setFlushMode(FlushModeType flushMode)
Set the flush mode that applies to all objects contained in the persistence context.

FlushModeTypeは、次の2つの値を持つ列挙型であることに注意してください。

FlushModeType AUTO(デフォルト)クエリの実行時に発生するフラッシュ。以来:JPA 1.0 FlushModeType COMMITフラッシュはトランザクションのコミット時に発生します。プロバイダーは他の時間にフラッシュする場合がありますが、必須ではありません。以来:JPA 1.0

この助けを願っています

可能な場合はいつでも、コンテナ管理トランザクションに行きます。 Bean管理トランザクションは、例外の可能性があるため、通常、かなり多くのコードを必要とします。また、エラーが発生しやすくなります(ロールバック、リソース管理)。

とはいえ、コンテナ管理モードではコミット後にフラッシュを使用します。そうすることで、ストレージモジュールでPersistenceExceptionの可能性をキャッチし、ユースケースモジュールのより意味のある例外に変換できます。これは、ここではストレージ固有の例外を処理したくないためです。なぜなら、JPAを使用しない何かのためにストレージモジュールを交換するかもしれないからです...

0
Dormouse