CMT的JTA交易划分究竟在哪里受到尊重?

时间:2009-10-08 14:42:07

标签: transactions glassfish ejb-3.0 jta

我正在尝试用CMT完全理解JTA的划分。我遇到的行为是,在EJB上只考虑该方法的第一个@TransactionAttribute,并且不会对具有不同@TransactionAttribute注释的同一个bean的后续方法调用进行调用。

示例:

@Stateless
@TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)
public class Foo implements IFoo {

   @EJB
   private IBar barBean;

   // inherits class transaction annotation of NOT_SUPPORTED
   public void doSomething() {
        barBean.doAction();
   }
}

@Stateless
@TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)
public class Bar implements IBar {

    public void doAction() {
        Entity entity = bar.find();
        entity.setName("new name");
        // fails with EJBException with TransactionRequiredException as cause
        save(entity);
    }

    public Entity find() {
        // return some persisted entity.
        return em.findById(1);
    }

    @TransactionAttribute(TransactionAttributeType.REQUIRED)
    public Entity save(entity) {
        em.persist(em.merge(entity));
        em.flush();
    }
}

我看到的行为是Bar.save()抛出TransactionRequiredException。所以这告诉我在save()上设置的REQUIRED注释不会创建事务。 REQUIRES_NEW也不起作用。如果我将save()移动到另一个EJB,它将按预期工作。

这是否意味着只有第一个TransactionAttribute注释被尊重,而不管后续的方法调用与不同的注释值相同?这是一个错误还是预期的行为?我似乎无法找到任何具体解释这一点的文档。我很欣赏这方面的任何见解。

我的筹码: EJB 3.0, Toplink Essentials, GF V2UR2

1 个答案:

答案 0 :(得分:2)

我对EJB 3规范的解读是,单个方法的事务规范会覆盖整个EJB的事务规范。因此,您所要求的期望应该是合理的,但是......

仅当您将bean方法用作EJB时才会这样做。当你从一个业务方法doAction()直接调用另一个,save()时,你没有使用EJB引用,因此这只是普通的旧Java - 容器没有涉及,所以容器没有机会干预

如果你对doAction()方法应用了必需的选项,我希望这可以工作。

这个理论与您对重构到另一个EJB的影响的结果一致。