我正在使用EJB和CMT事务的应用程序。我有一个EJB(让我们称之为EJB1),其中CMT被注释定义为“requires_new”,如:
@TransactionAttribute(TransactionAttributeType.REQUIRED)
由于到目前为止还没有交易,因此会创建一个交易。现在,这个EJB1调用另一个EJB(EJB2)。我在研究中发现的是创建另一个事务的独特方式是使用“requires_new”,如:
@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
它完美地工作,创建了新的事务。问题在于回滚情况:当EJB2发生故障时,只会按预期回滚事务。当EJB1失败时,所有这些都被回滚,正如预期的那样但不是我需要的......
我需要的是类似的,只是这个区别:当EJB1失败时,它应该回滚,但我希望EJB2如果没有失败仍然会被提交。
我让我理解了吗?当父级失败时,我不想要一个子事务。对于我从主EJB调用的每个EJB,我想要一个独立的事务(比如并行事务)。
答案 0 :(得分:1)
您提到的事务属性应该在您的方案中按预期工作;如果对EJB2的调用成功,它将自行提交,因为它是requires_new。但是,在这种情况下,如果在EJB2调用之前弹出未处理的异常,则可能甚至不会调用它,从而给出所有内容都被回滚的印象。
如果不是这种情况,您还可以通过注入EJBContext并调用context.setRollbackOnly()来控制EJB1中的事务。这将标记当前事务在完成时回滚,并且它将按预期工作。
答案 1 :(得分:0)
我无法确认您的陈述:
它完美地工作,创建了新的事务。问题在于回滚情况:当EJB2发生故障时,只会按预期回滚事务。当EJB1失败时,所有这些都被回滚,正如预期的那样但不是我需要的......
我有EJB1的方法,没有任何注释(我猜是默认为REQUIRED
),而EJB2的方法用@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
注释。
EJB1正在调用EJB2。在EJB2中,我持有一个实体并离开了该方法。回到EJB1中,我通过抛出异常引起了回滚。 最终,EJB2的变化仍然存在,尽管EJB1已经被回滚。
此外,在放弃EJB2之后,您已经可以在数据库中看到已提交的更改(使用断点暂停EJB1的执行)。