15

現在、Hibernate のドキュメントを読んでいるときに、次の引用に出くわしました。

Session が例外 (SQLException を含む) をスローした場合は、すぐにデータベース トランザクションをロールバックし、Session.close() を呼び出して、Session インスタンスを破棄します。Session の特定のメソッドは、セッションを一貫した状態のままにしません。Hibernate によってスローされた例外は、回復可能として扱うことはできません。最終ブロックで close() を呼び出して、セッションが閉じられることを確認します。

私に関する限り、これはすべて理にかなっていますが、コミットもロールバックもされていないトランザクションでセッションを閉じると、どのような影響があるのでしょうか?

たとえば、次のことを考慮してください。

  session = getSessionFactory().openSession();
  session.beginTransaction();
  session.save(carObject);
  //session.getTransaction().commit();
  session.close();

コミットがコメントアウトされ、ここでロールバックが呼び出されない場合、session.close() の予想される動作は何ですか? コミットを自動的にロールバックするだけですか?「ハングしている」トランザクションを残しますか? 等

(これは明らかに良い習慣ではないことを理解しています.基礎となる概念についてもう少し理解しようとしています.)

4

1 に答える 1

14

私はHibernateを少し掘り下げました:

永続セッションは、ライフサイクルを JDBC 接続からある程度独立させます。Hibernate を閉じるとSession、接続が解放されます。「接続を解放する」の正確な意味は、最初に接続がどのように取得されたかによって異なります。

  • 接続が手動で (たとえば を介してsessionFactory.openStatelessSession(connection)) 提供された場合、呼び出し時に未完了のトランザクションで接続が返されます。session.close()
  • それ以外の場合、呼び出しsession.close()は通常呼び出しで終了しますconnection.close()

Hibernate による自動セッション フラッシュやトランザクション コミット/ロールバックは行われません。JPA のEntityManager.

したがって、最終的に何が起こるかは、接続プロバイダー/データ ソースによって異なります。C3POでは、接続がプールに返されると、未完了のトランザクションがロールバックされます。一方、JTA 接続を管理している場合、実際のトランザクション処理は完全にアプリケーションの範囲外になる可能性があります。

于 2013-10-16T09:38:47.500 に答える