首页 > 解决方案 > Singleton 中上下文类型为 TRANSACTION 的 EntityManager 会加入外部 bean 管理的事务吗?

问题描述

假设我有一个Singleton豆子,EntityManager里面有一个。单例还指定(在方法或类级别)事务属性REQUIRED。实体管理器是通过@PersistenceContext指定持久性上下文类型的注入获得的TRANSACTION。出于所有意图和目的,如果使用现有事务调用此单例上的方法,则实体管理器应加入事务或可能通过代理提供链接到该事务的现有方法。如果在事务之外调用此类方法,则将在方法调用期间启动新事务。

现在假设我们有第二个 bean,它使用 bean 管理的事务并注入单例。如果它显式启动用户事务,然后调用单例上的方法,该方法中的实体管理器会加入该用户事务吗?从 bean 管理到容器管理的事务上下文的跳转会起作用吗?我知道反过来不会并形成障碍。

单例类:

@Singleton
@TransactionAttribute(TransactionAttributeType.REQUIRED)
public class PersistenceSingleton {

    @PersistenceContext(unitName = "test", type = PersistenceContextType.TRANSACTION)
    private EntityManager em;

    public void doStuff() {

        // perform actions with the entity manager that imply changes in the database

    }

}

具有用户事务的 bean(也可能是无状态的或有状态的):

@Singleton
@TransactionManagement(TransactionManagementType.BEAN)
public class PersistenceFacade {

    @EJB
    private PeristenceSingleton ps;

    @Resource
    private UserTransaction userTx;

    public void doStuff() {
        userTx.begin();
        ps.doStuff();
        userTx.commit();
    }

}

在调用时是否考虑到doStuff()在 get 方法中启动的事务?实体管理器是否在并发访问期间自动加入事务并按照事务隔离的预期表现?PersistenceFacadedoStuff()PersistenceSingleton

标签: javajpajakarta-eetransactionsentitymanager

解决方案


UserTransaction 用于更改默认事务分界,但我们仍然控制 JTA 事务。

https://www.javacodegeeks.com/2013/03/types-of-entity-managers-application-managed-entitymanager.html说:

如果您有 UserTransaction,您可以开始划分要在事务中执行的内容。请注意,您仍在控制 JTA 事务

因此持久化上下文传播规则将应用于 UserTransaction 划分。

亲 JPA 书 说:

当在事务范围的实体管理器上调用方法时,它必须首先查看是否存在传播的持久性上下文。如果存在,则实体管理器使用此持久性上下文来执行操作。在此组件或任何其他组件中的所有后续事务范围实体管理器操作将随后使用此新创建的持久性上下文。此行为独立于是否使用了容器管理或 bean 管理的事务划分。

你的问题的答案是肯定的(第一个问题)

实体管理器是否在并发访问期间自动加入事务并按照事务隔离的预期表现?

实体管理器检查传播的持久性上下文的存在并使用它。


推荐阅读