EJB 3 CMT如何在没有回滚子事务的情况下回滚第一个事务?

时间:2012-03-21 18:36:59

标签: java java-ee

我正在使用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,我想要一个独立的事务(比如并行事务)。

2 个答案:

答案 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的执行)。