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

时间:2011-12-11 13:39:19

标签: java google-app-engine jpa transactions

我最近开始在Google App Engine上使用JPA。在阅读一些例子时,我注意到对象持久化的方式存在一些变化。在一个案例中,我见过这样的事情:

entityManager.getTransaction().begin();
entityManager.persist(object);
entityManager.getTransaction().commit();

在其他情况下,我没有看到使用getTransaction()。我只看到entityManager.persist(object)。什么时候适合使用getTransaction()

4 个答案:

答案 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。