JPA - 持久化对象时何时使用 getTransaction()
Posted
技术标签:
【中文标题】JPA - 持久化对象时何时使用 getTransaction()【英文标题】:JPA - When to use getTransaction() when persisting objects 【发布时间】:2012-01-17 20:38:15 【问题描述】:我最近开始在 Google App Engine 上使用 JPA。在阅读一些示例时,我注意到对象的持久化方式存在一些变化。在一种情况下,我见过这样的事情:
entityManager.getTransaction().begin();
entityManager.persist(object);
entityManager.getTransaction().commit();
在其他情况下,我看不到getTransaction()
的使用。我只是看到entityManager.persist(object)
。什么时候使用getTransaction()
比较合适?
【问题讨论】:
【参考方案1】:如果您使用容器管理的EntityManager
,那么您使用的是 JTA 事务。因此,您不需要(更准确地说 - 您不能)干扰使用 entityManager.getTransaction()
获取的 EntityManager
的事务。 JTA 启动并提交您的事务。
如果您使用应用程序管理 EntityManager
并且您不想参与 JTA 事务,那么您需要自己管理它们(称为资源本地实体管理器)。
大多数情况下,与EntityManager.getTransaction()
一起使用的应用程序托管EntityManager
用于Java SE 环境。
编辑:您可能对JPA 2.0 specification 中的7.5 控制交易部分感兴趣。
【讨论】:
从未与 GAE 合作过 - 认为这是更多以 JPA 事务为中心的问题。感谢您的澄清。 即使从数据库中获取实体,我们是否也需要获取事务...使用 entitymanager.find 方法...只是好奇..因为我什至看不到一个示例..在哪里进行交易。 begin() 在 entitymanger.find 方法之前...:) :)【参考方案2】:当您在应用程序中显式处理事务时,您会使用getTransaction()
。另一方面,如果您让容器为您处理事务,则无需显式地开始/结束事务。本质上,我们处理的是Container Managed Transactions (CMT) 和Bean Managed Transactions (BMT) 之间的区别。
一般来说,当您需要对事务处理进行更多控制时,或者当有其他技术要求(例如,两阶段提交、分布式事务、XA 事务)无法满足时,您会使用 BMT使用 CMT。此外,当您的应用程序部署在应用程序服务器之外并依赖于 Java SE 时,您将使用 BMT。
【讨论】:
【参考方案3】:在 GAE 中没有 Java EE/JTA,因此请忽略 bean 管理事务 (BMT) 和容器管理事务 (CMT) 等术语。
您的工作要么是事务性的(您希望多个对象一次进入数据存储区,或者全部失败 - 这是您使用 getTransaction() 的地方),要么是非事务性的(所有对象都一个接一个地进入数据存储区,并且一个persist的失败不会影响其他人——这就是你调用persist()/merge()/remove())的地方。
【讨论】:
GAE 中有 Java EE 的一些部分,只是没有完整的配置文件。例如,JPA 是一个 Java EE API,但它的行为“有点不同”。【参考方案4】: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();
【讨论】:
以上是关于JPA - 持久化对象时何时使用 getTransaction()的主要内容,如果未能解决你的问题,请参考以下文章
JPA 持久性和 Hibernate javassist 对象
何时使用/不使用,@OneToOne 和 @ManyToOne