使用新的JTA事务时,其他事务中的PersistenceContexts会发生什么?

时间:2014-06-06 02:51:45

标签: java java-ee jpa ejb jta

我正在使用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需要新事务,因此会创建新的持久性上下文,然后在方法结束时提交。问题是另一个事务的预先存在的持久化上下文会发生什么。

  1. 如果调用了modifyEntities,然后调用了cullOldEntities,那么如果cullOldEntities首先完成并且持久化上下文已经提交,它们会同时运行modifyEntities持久化上下文吗?

  2. modifyEntities的持久性上下文是否与所做的更改同步?

  3. 如果没有修改实体会发生什么?

  4. 如何通过并发修改进行批量删除?

2 个答案:

答案 0 :(得分:0)

EntityManager不是线程安全的。因此,如果没有锁定,则最后一次提交将覆盖在另一个事务中进行的更改。

答案 1 :(得分:0)

行为(以及对事务传播设计的后续影响)取决于用于持久性上下文的作用域的类型。这两种是Transaction scopedExtended Persistence context(可以跨越多个事务)。对于事务范围的持久性上下文 - 在cullOldEntities()方法调用开始之前, 容器将暂停继承的事务(如果有)并将启动新事务 事务(因为属性TransactionAttributeType.REQUIRES_NEW)。当在实体管理器上调用需要事务的实体管理器方法时,它将检查当前事务的活动持久性上下文,并且不会找到任何事务管理器。一个新的 将从该调用开始创建持久化上下文,并且此持久性上下文将是 活动持久性直到方法contextcullOldEntities()结束。因为交易 在cullOldities开始()与前一个(如果有的话)不同,由前一个持久化上下文管理的实体 这个新的不可见。

然而,扩展持久化上下文通常作用于绑定到它的有状态会话bean。 有状态会话bean的扩展实体管理器始终使用相同的持久性 上下文。有状态会话bean与单个扩展持久性上下文相关联 在创建bean实例时创建,并在删除bean实例时关闭。