假设我有一个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()
上调用PersistenceFacade
时,是否考虑到在doStuff()
的方法PersistenceSingleton
中启动的事务?实体管理器是否会自动加入事务,并在并发访问期间表现出与事务隔离相同的预期效果?
答案 0 :(得分:1)
UserTransaction用于更改默认事务划分,但我们仍控制JTA事务。
如果具有UserTransaction,则可以开始划分事务中要执行的内容。请注意,您仍在控制 JTA交易
因此,持久性上下文传播规则将应用于UserTransaction划分。
专业JPA书中说:
在事务范围的实体管理器上调用方法时,它 必须首先查看是否存在传播的持久性上下文。如果 一个存在的实体管理器使用此持久性上下文来进行 进行操作。所有后续的交易范围的实体管理器 此组件或任何其他组件中的操作将在此之后使用 新创建的持久性上下文。此行为独立起作用 容器管理的事务划分还是Bean管理的事务划分 已被使用。
您的问题的答案是肯定的(第一个问题)
实体管理器是否自动加入事务并表现出来 并发访问期间从事务隔离中获得预期的结果?
实体管理器检查传播的持久性上下文的存在并使用它。