【问题标题】:JPA - When to use getTransaction() when persisting objectsJPA - 持久化对象时何时使用 getTransaction()
【发布时间】:2012-01-17 20:38:15
【问题描述】:

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

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

在其他情况下,我看不到getTransaction() 的使用。我只是看到entityManager.persist(object)。什么时候使用getTransaction()比较合适?

【问题讨论】:

    标签: java google-app-engine jpa transactions


    【解决方案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(); 
      }
      

      【讨论】:

        猜你喜欢
        • 2012-10-24
        • 1970-01-01
        • 2011-01-19
        • 2017-04-09
        • 1970-01-01
        • 1970-01-01
        • 2017-10-10
        • 2014-06-11
        • 2012-05-08
        相关资源
        最近更新 更多