java当使用新的JTA事务时,其他事务中的PersistenceContext会发生什么变化?
我将CMT与无状态EJB一起使用。假设我有两种方法,一种是EJB计时器超时,另一种是修改现有实体:
@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
@Timeout
public void cullOldEntities() {
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaDelete<T> cd = cb.createCriteriaDelete(clazz);
Root<T> root = cd.from(clazz);
Path<Date> dateCreatedPath = root.get("lastUpdated");
cd.where(cb.lessThan(dateCreatedPath, dateOfExpiry()));
em.createQuery(cd).executeUpdate();
}
public void modifyEntities(...)
由于cullOldEntities需要一个新事务,因此会创建一个新的持久性上下文,然后在方法结束时提交该上下文。问题是另一个事务的先前存在的持久性上下文会发生什么情况
如果先调用modifyEntities,然后调用cullOldEntities,使其并发运行,那么如果cullOldEntities先完成并提交了其持久性上下文,modifyEntities持久性上下文会发生什么情况
modifyEntities的持久性上下文是否与所做的更改同步
如果没有,修改实体时会发生什么
我怎样才能在并发修改的情况下安全地执行批量删除
# 1 楼答案
EntityManager不是线程安全的。因此,如果不锁定最后一次提交,它将覆盖在另一个事务中所做的更改
# 2 楼答案
行为(以及对事务传播设计的后续影响)取决于用于持久性上下文的作用域类型。这两种类型是
Transaction scoped
和Extended Persistence context
(可以跨越多个事务)。对于事务范围的持久性上下文-在cullOldEntities()
方法调用开始之前, 容器将暂停继承的事务(如果有的话),并启动一个新的 事务(因为属性TransactionAttributeType.REQUIRES_NEW)。当在实体管理器上调用需要事务的实体管理器方法时,它将检查当前事务是否存在活动的持久性上下文,但找不到。一个新的 将从该调用开始创建持久性上下文,该持久性上下文将是 活动持久性,直到方法contextcullOldEntities()结束。因为交易 在cullOldEntities()中启动的实体不同于之前的实体(如果有),即由上一个持久性上下文管理的实体 不会被这个新的人看到然而,扩展持久性上下文的作用域通常是它绑定到的有状态会话bean。 有状态会话bean的扩展实体管理器始终使用相同的持久性 上下文有状态会话bean与一个扩展持久性上下文相关联,该上下文是 创建bean实例时创建,删除bean实例时关闭