Transactions EJB3.1 TransactionAttributeType.REQUIRES_NEW和setRollbackOnly

Transactions EJB3.1 TransactionAttributeType.REQUIRES_NEW和setRollbackOnly,transactions,glassfish,ejb,Transactions,Glassfish,Ejb,请帮助我了解EJB3.1中的事务。我正在使用GlassFish v3,出现以下情况: @Stateless @LocalBean public class BeanA { @Inject BeanB bean; /* which has no TransactionAttribute set */ @Resource SessionContext context; public void run() { ... for (...) {

请帮助我了解EJB3.1中的事务。我正在使用GlassFish v3,出现以下情况:

@Stateless
@LocalBean
public class BeanA {

    @Inject BeanB bean; /* which has no TransactionAttribute set */
    @Resource SessionContext context;

    public void run() {
        ...
        for (...) {
            process(someValue);
        }
    }

    @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
    public void process(String someValue) {

        try {

            SomeEntity entity = bean.getEntity(someValue);
            entity.setSomeProperty("anotherValue");

            ...

        } catch(CustomException e)  {
            this.context.setRollbackOnly();
        }
    }

}
从servlet调用BeanA.run。我希望将每个迭代都视为一个单独的事务。我原以为使用TransactionAttributeType.REQUIRES_NEW会意识到这一点,但在调用setRollbackOnly之后,我在beanB的后续迭代中得到了javax.ejb.EJBTransactionRolledbackException。但奇怪的是,当我将run()以外的所有内容移动到一个新的BeanC并调用BeanC.process时,它确实工作了。我错过了什么?有人能解释一下为什么会这样吗

编辑:想一想:这是因为容器不拦截对同一EJB中的方法的调用吗?(这似乎是合理的)

编辑2:是的,在这里找到答案:(我必须知道答案才能找到:)

在这里找到答案:


简而言之:容器不拦截本地方法调用,因此SetRollback只标记了用于回滚的唯一事务,解释了异常情况。

老问题,但为了完整性起见

实际上,在类中直接调用诸如
@TransactionAttribute
之类的注释时,不会对其进行处理。这是因为您直接调用它,就像在过程函数中一样。它不经历EJB生命周期(包括拦截器)

但是有一种方法可以做到这一点。您需要注入self类并使用该引用:

// Bean A

@Resource SessionContext context;

public void run() {
    ...
    for (...) {
       context.getBusinessObject(BeanA.class).process(someValue);
    }
}
通过这种方式,它将创建进程
@TransactionAttribute


虽然它可以工作,但我不确定这是否是一个好的设计。

请为您的问题提供答案,并将其标记为已解决,以便正确标记问题。此外,以下资源可能对您有用:感谢您的输入。我还得再等7个小时才能回答我自己的问题。