【问题标题】:Is there a difference between getTransaction().begin()/.commit() and joinTransaction() with JPA2/EclipseLink?getTransaction().begin()/.commit() 和 joinTransaction() 与 JPA2/EclipseLink 之间有区别吗?
【发布时间】:2023-03-07 14:10:01
【问题描述】:

我正在使用带有注释的 JPA2 和 EclipseLink,我想知道两者之间是否有区别

EntityManager em = ...
// Some action
em.joinTransaction();
em.close();

EntityManager em = PU.entityManager();
em.getTransaction().begin();
// Some action
em.getTransaction().commit();
em.close();

我一般应该更喜欢哪一个?

【问题讨论】:

    标签: java database jpa orm eclipselink


    【解决方案1】:

    EntityManager.joinTransaction 用于 JTA 事务(暗示持久性单元被配置为使用 JTA 事务)而EntityTransaction.begin 旨在用于资源本地实体管理器(暗示不使用 JTA管理交易)。因此,它们都适用于不同的场景。

    第一种情况,即 EntityManager.joinTransaction 很少使用,因为当您需要 JTA 事务支持时,您经常会注入容器管理的 EntityManager 实例。容器管理的 EntityManagers 被注入(使用 @PersistenceContext 注释)到现有 JTA 事务(由容器管理)的上下文中,因此不需要显式加入事务。只有在应用程序管理的EntityManagers 事件中,您才需要加入现有事务。应用程序管理的EntityManagers 不是由容器注入的;相反,容器只能注入一个EntityManagerFactory 实例(使用@PersistenceUnit 注释),应用程序使用该实例来获取EntityManager 实例。

    在第二种情况下,即EntityTransaction.begin,将不会使用 JTA 事务来确定任何事务工作的范围。相反,事务是资源本地的,因为对持久性上下文所做的任何更改都将作为原子单元进行跟踪,直到调用EntityTransaction.commit。很少有人在 Java EE 应用程序中使用资源本地实体管理器,因为您通常希望 EJB(和 EJB 容器)划分事务边界,而不是应用程序源代码。此外,使用本地资源事务执行的任何事务工作都不会被可能已经启动的 JTA 事务跟踪,从而导致应用程序中的事务活动的行为模糊、混乱和模棱两可。

    【讨论】:

    • 那么在非 Java-EE 应用程序中 begin/commit 是要走的路吗?
    • 是的,没错。如果我的回答不够清楚,joinTransaction 仅在 JTA 实体管理器尚未与 JTA 事务关联时才被调用。
    猜你喜欢
    • 2014-12-05
    • 2015-07-14
    • 2016-01-24
    • 2015-10-14
    • 1970-01-01
    • 2011-08-20
    • 1970-01-01
    • 1970-01-01
    • 2012-02-16
    相关资源
    最近更新 更多