JPA – 何时在持久化对象时使用getTransaction()

我最近开始在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事务,那么您需要自己管理它们(它称为资源本地实体管理器)。

最典型的是,在Java SE环境中使用与EntityManager.getTransaction()使用的应用程序管理的EntityManager

编辑:您可能对从JPA 2.0规范中的secion 7.5控制事务感兴趣。

在GAE中没有Java EE / JTA,因此忽略诸如bean管理事务(BMT)和容器管理事务(CMT)之类的术语。

您的工作要么是事务性的(您希望多个对象一次转到数据存储区,要么全部失败 – 这是您使用getTransaction()的地方),或者是非事务性的(其中所有内容都是逐个转到数据存储区,并且一个持久化失败不会影响其他人 – 这就是你只需要调用persist()/ merge()/ remove())的地方。

Google App Engine具有其事务管理( https://developers.google.com/appengine/docs/java/datastore/transactions ),但JPA事务接口不了解某些GAE基础function(即实体组)。

因此,应由您的应用程序决定在事务中执行哪些操作,哪些操作不执行。 您应该放入必须以primefaces方式执行的事务操作。

请记住,在事务中执行级联操作和关系操作是最佳做法,因为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无法满足的其他技术要求(例如,两阶段提交,分布式事务,XA事务)时,您将使用BMT。 此外,当您的应用程序部署在应用程序服务器之外并依赖于Java SE时,您将使用BMT。