最近、Google App EngineでJPAの使用を開始しました。いくつかの例を読んで、オブジェクトの永続化方法にいくつかのバリエーションがあることに気付きました。あるケースでは、私はこのようなものを見ました:
_entityManager.getTransaction().begin();
entityManager.persist(object);
entityManager.getTransaction().commit();
_
他の場合では、getTransaction()
の使用がわかりません。単にentityManager.persist(object)
と表示されます。いつgetTransaction()
を使用するのが適切ですか?
コンテナー管理EntityManager
を使用している場合は、JTAトランザクションを使用しています。したがって、entityManager.getTransaction()
を使用してフェッチされたEntityManager
のトランザクションに干渉する必要はありません(より正確には-できません)。 JTAが開始し、トランザクションをコミットします。
アプリケーション管理のEntityManager
を使用していて、JTAトランザクションの一部になりたくない場合は、それらを自分で管理する必要があります(リソースローカルエンティティマネージャーと呼ばれます)。
最も一般的には、EntityManager.getTransaction()
で動作するアプリケーション管理のEntityManager
は、Java SE環境で使用されます。
編集: JPA 2.0仕様 のセクション7.5制御トランザクションに興味があるかもしれません。
GAEにはJava EE/JTAがないため、Bean管理トランザクション(BMT)、コンテナ管理トランザクション(CMT)などの用語は無視してください。
作業は、トランザクション(複数のオブジェクトを一度にデータストアに移動するか、すべて失敗させる-これはgetTransaction()を使用する場所)、または非トランザクション(すべてが1つずつデータストアに移動する場所)、および1つの永続化の失敗は他に影響しません-これは、persist()/ merge()/ remove()を呼び出すだけです)。
Google App Engineにはトランザクション管理( https://developers.google.com/appengine/docs/Java/datastore/transactions )がありますが、JPAトランザクションインターフェースは基盤となるGAEの一部を認識していません機能(つまり、エンティティグループ)。
したがって、トランザクションで実行する操作と実行しない操作を決定するのはアプリケーションの責任です。アトミックに実行する必要があるトランザクション操作を配置する必要があります。
JPAは多くのクエリをトリガーし、データの不整合を引き起こす可能性があるため、トランザクションでカスケードアクションと関係操作を実行するためのベストプラクティスとして覚えておいてください。
JPA2でトランザクションを使用する例:
import javax.persistence.EntityTransaction;
EntityTransaction txn = em.getTransaction();
txn.begin();
try {
//do something with your database
txn.commit();
}
finally {
if (txn.isActive())
txn.rollback();
}
アプリケーションでトランザクションを明示的に処理している場合は、getTransaction()
を使用します。一方、コンテナにトランザクションを処理させる場合は、トランザクションを明示的に開始/終了する必要はありません。基本的に、 コンテナ管理トランザクション (CMT)と Bean管理トランザクション (BMT)の違いを扱っています。
一般に、トランザクション処理をより詳細に制御する必要がある場合、またはCMTを使用して満たすことができない追加の技術要件(たとえば、2フェーズコミット、分散トランザクション、XAトランザクション)がある場合は、BMTを使用します。また、アプリケーションがアプリケーションサーバーの外部にデプロイされ、Java SEに依存している場合は、BMTを使用します。