我最近开始在Google App Engine上使用JPA。在阅读一些例子时,我注意到对象持久化的方式存在一些变化。在一个案例中,我见过这样的事情:
entityManager.getTransaction().begin();
entityManager.persist(object);
entityManager.getTransaction().commit();
在其他情况下,我没有看到使用getTransaction()
。我只看到entityManager.persist(object)
。什么时候适合使用getTransaction()
?
答案 0 :(得分:19)
如果您使用容器管理EntityManager
,那么您正在使用JTA事务。因此,您不需要(更确切地说 - 您不能)干扰EntityManager
使用entityManager.getTransaction()
提取的交易。 JTA启动并提交您的交易。
如果您使用应用程序管理EntityManager
并且您不想参与JTA事务,那么您需要自己管理它们(它被称为资源本地实体管理器)。
最常见的是,在Java SE环境中使用与EntityManager
一起使用的应用程序管理EntityManager.getTransaction()
。
编辑:您可能对JPA 2.0 specification中的secion 7.5控制交易感兴趣。
答案 1 :(得分:5)
在GAE中没有Java EE / JTA,因此忽略诸如bean管理事务(BMT)和容器管理事务(CMT)之类的术语。
您的工作要么是事务性的(您希望多个对象一次转到数据存储区,要么全部失败 - 这是您使用getTransaction()的地方),或者是非事务性的(其中所有内容都是逐个转到数据存储区) ,并且一个持久化的失败不会影响其他人 - 这就是你只需要调用persist()/ merge()/ remove())。
答案 2 :(得分:3)
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();
}
答案 3 :(得分:0)
当您明确处理应用程序中的事务时,您将使用getTransaction()
。另一方面,如果让容器为您处理事务,则无需显式开始/结束事务。基本上,我们正在处理Container Managed Transactions(CMT)和Bean Managed Transactions(BMT)之间的差异。
通常,当您需要对事务处理进行更多控制时,或者当存在无法满足的其他技术要求(例如,两阶段提交,分布式事务,XA事务)时,您将使用BMT。使用CMT。此外,当您的应用程序部署在应用程序服务器之外并依赖于Java SE时,您将使用BMT。