如果 EJB 方法忽略其他方法的事务属性,我如何微观管理 EJB 事务?

How can I micromanage EJB transactions if EJB methods ignore the transaction attributes of other methods?

我有一个带有 2 个方法的 EJB:

@Stateless
public FooFacade implements FooFacadeRemote {

    ...

    @TransactionAttribute(javax.ejb.TransactionAttributeType.NEVER)
    public void saveFoos(List<Foo> foos) {
        for(Foo foo: foos) {
            saveFoo(foo);
        }
    }

    @TransactionAttribute(javax.ejb.TransactionAttributeType.REQUIRED)
    private void saveFoo(Foo foo) {
        em.persist(foo);
    }
}

我刚刚发现调用自己方法的 EJB 会忽略那些方法的 TransactionAttributeType。所以我得到了交易所需的异常,因为 saveFoo "sees" TransactionAttributeType 为 NEVER.

我知道解决这个问题的方法是让另一个 EJB 实例来执行任务:

@EJB(name = "FooFacade")
private FooFacadeRemote self;

@TransactionAttribute(javax.ejb.TransactionAttributeType.NEVER)
public void saveFoos(List<Foo> foos) {
    for(Foo foo: foos) {
        self.saveFoo(foo);
    }
}

但这真的需要吗?我的意思是,我不希望 saveFoo 一定要公开。

不需要单独的EJB,只需要通过EJB代理调用方法即可。如果这是无状态或单例会话 bean,则只是对同一 EJB 的 EJB 引用:

@Stateless
public class MyEJB implements MyEJBInterface {
    @EJB MyEJBInterface self;
    ...

    @TransactionAttribute(javax.ejb.TransactionAttributeType.NEVER)
    public void saveFoos(List<Foo> foos) {
        for (Foo foo: foos) {
            self.saveFoo(foo);
        }
    }
}

如果这是有状态会话 bean,则注入 @Resource SessionContext,并使用 getBusinessInterface 获取同一个有状态会话 bean 实例的 EJB 代理。