Java 中间带有 POJO 调用的 EE 事务传播

Java EE Transaction propagation with POJO calls in-between

下面是一个EJB的源代码class1:

@TransactionAttribute(TransactionAttributeType.REQUIRED)
public class EJB1 {

  public void method1(Callback callback) {
    callback.createObject();
    Entity1 entity = new Entity1();
    try {
      entityManager.persist(entity1);
      entityManager.flush()
    } catch(Exception e) {
      //do something
    }
  }
}

Callback-class 是一个没有 TransactionalContext 的 POJO 并调用 EJB 2 的另一个方法(通过 JNDI 查找),再次 TransactionAttribute.REQUIRED:

public class Callback {

  public void createObject() {
    getEJB2().createObject();
  }

  public EJB2 getEJB() {
    //lookup EJB2 via JNDI
  }
}

EJB2源代码:

@TransactionAttribute(TransactionAttributeType.REQUIRED)
public class EJB2 {

  public void createObject() {
     Entity2 entity = new Entity2();
     entityManager.persist(entity);
      entityManager.flush()
  }
}

如果在 EJB1 中持久化 entity1 失败(例如,由于数据库中的 UniqueConstraint),EJB1 的事务被成功标记为回滚。例如,在 EJB1 的 try-catch 中尝试删除创建的对象时不起作用(因为事务已标记为回滚)。

虽然在EJB2中创建并持久化的对象仍然存在并且没有回滚! 设置 - 对于实验性使用 - 强制创建的 EJB2 事务上下文仍然可以正常工作(表明 EJB2 不创建新事务而是通过现有事务中的 REQUIRED 参与)。

但是为什么EJB2中新建的对象没有回滚?

同时,我们将 Java EE 应用程序服务器从 WebLogic 10.0 更改为 GlassFish 3,并将使用的持久性提供程序从 OpenJPA 1.0.0.1 更改为 EclipseLink 2.5,从而解决了这个问题。 1.

其中一项更改解决了问题,可能是切换到 EclipseLink。 现在事务被标记为回滚(这不是之前的问题并且完全符合预期)并且由于回滚删除了 Entity2 的新持久实例。

对不起,我之前没有提到这个信息,所以可能无法找到原因。