Where exactly is the JTA Transaction demarcation for CMT respected?
我正在尝试完全理解 JTA 与 CMT 的划分。我遇到的行为是,在 EJB 上仅尊重该方法的第一个 @TransactionAttribute,而对具有不同 @TransactionAttribute 注释的同一 bean 的后续方法调用则没有。
示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | @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,
顶联要点,
GF V2UR2
我对 EJB 3 规范的解读是,单个方法的事务规范会覆盖整个 EJB 的事务规范。因此,您对 REQUIRED 应该适用的期望似乎是合理的,但是 ...
仅当您将 bean 方法用作 EJB 时。当您从一个业务方法 doAction() 直接调用另一个业务方法 save() 时,您没有使用 EJB 引用,因此这只是普通的旧 Java - 不涉及容器,因此容器没有机会进行干预.
如果您将所需的选项应用于您的 doAction() 方法,我希望它可以工作。
这个理论与你对重构到另一个 EJB 的影响的发现是一致的。