Red Hat Training
A Red Hat training course is available for Red Hat JBoss Web Server
12.2.2. JTA を使用する
永続化層をアプリケーションサーバー (例えば、 EJB セッション Bean の背後) で実行する場合、 Hibernate から取得するすべてのデータソースコネクションは、自動的にグローバル JTA トランザクションの一部になります。EJB を使わずに、スタンドアロンの JTA 実装を導入することもできます。JTA 統合のために、Hibernate は2つの戦略を提供します。
Bean 管理トランザクション(BMT)を使い、
Transaction
API を使う場合、 Hibernate はアプリケーションサーバーに BMT トランザクションの開始と終わりを告げます。すなわち、トランザクション管理のコードは、管理のない環境と同じになります。
// BMT idiom Session sess = factory.openSession(); Transaction tx = null; try { tx = sess.beginTransaction(); // do some work ... tx.commit(); } catch (RuntimeException e) { if (tx != null) tx.rollback(); throw e; // or display error message } finally { sess.close(); }
トランザクション境界として
Session
を使いたい場合、簡単にコンテキストを伝播する getCurrentSession()
機能があるので、 JTAの UserTransaction
API を直接使用すべきでしょう。
// BMT idiom with getCurrentSession() try { UserTransaction tx = (UserTransaction)new InitialContext() .lookup("java:comp/UserTransaction"); tx.begin(); // Do some work on Session bound to transaction factory.getCurrentSession().load(...); factory.getCurrentSession().persist(...); tx.commit(); } catch (RuntimeException e) { tx.rollback(); throw e; // or display error message }
CMT では、トランザクション境界をセッション Bean のデプロイメントディスクリプタで定義し、プログラムでは行いません。コードは次のように少なくなります:
// CMT idiom Session sess = factory.getCurrentSession(); // do some work ...
CMT/EJB の中では、ロールバックが自動的に実施されます。セッション Bean のメソッドにより投げられた処理されていない
RuntimeException
は、グローバルトランザクションをロールバックするようコンテナに伝えるためです。これは、BMT もしくは CMT と一緒に Hibernate Transaction
API を使う必要はまったくなくトランザクションにバインドする「現在の」セッションを自動伝搬できます。
Hibernate のトランザクションファクトリを設定する際に、JTA を直接使う (BMTの) 場合は
org.hibernate.transaction.JTATransactionFactory
を、 CMT セッション Bean の中では org.hibernate.transaction.CMTTransactionFactory
を選択してください。hibernate.transaction.manager_lookup_class
をセットすることも忘れないでください。なお、hibernate.current_session_context_class
は、セットしないか(後方互換)、"jta"
をセットしてください。
getCurrentSession()
オペレーションは、JTA 環境で欠点が1つあります。デフォルトで使われる after_statement
コネクションリリースモードを使用する上で、警告が1つあります。JTA 仕様の制約のために、scroll()
または iterate()
が返した、閉じられていない ScrollableResults
または Iterator
インスタンスを Hibernate が自動的にクリーンアップすることはできません。finally
ブロックの中で、 ScrollableResults.close()
または Hibernate.close(Iterator)
を明示的に呼び出して、基盤のデータベースカーソルを解放 しなければなりません。多くのアプリケーションでは、 JTA か CMT コードから、scroll()
や iterate()
の使用を簡単に避けることができます。