Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/342.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java EJB3CMT如何回滚第一个事务而不回滚子事务?_Java_Jakarta Ee - Fatal编程技术网

Java EJB3CMT如何回滚第一个事务而不回滚子事务?

Java EJB3CMT如何回滚第一个事务而不回滚子事务?,java,jakarta-ee,Java,Jakarta Ee,我正在使用一个带有EJB和CMT事务的应用程序。我有一个EJB(我们称之为EJB1),其CMT通过注释定义为“requires_new”,如: @TransactionAttribute(TransactionAttributeType.REQUIRED) 因为到目前为止还没有交易,所以它创建了一个。现在,这个EJB1调用另一个EJB(EJB2)。我在研究中发现,创建另一个事务的独特方式是使用“requires_new”,如: 它工作得很好,新的事务被创建。问题在于回滚情况:当EJB2失败时,

我正在使用一个带有EJB和CMT事务的应用程序。我有一个EJB(我们称之为EJB1),其CMT通过注释定义为“requires_new”,如:

@TransactionAttribute(TransactionAttributeType.REQUIRED)
因为到目前为止还没有交易,所以它创建了一个。现在,这个EJB1调用另一个EJB(EJB2)。我在研究中发现,创建另一个事务的独特方式是使用“requires_new”,如:

它工作得很好,新的事务被创建。问题在于回滚情况:当EJB2失败时,只有它的事务被回滚,正如预期的那样。当EJB1失败时,所有这些都将回滚,正如预期的那样,但不是我所需要的

我需要的是类似的,只是这个区别:当EJB1失败时,应该回滚,但如果EJB2没有失败,我希望它仍然提交


我让我明白了吗?当父事务失败时,我不希望子事务每次都回滚。对于我从主EJB调用的每个EJB,我需要一个独立的事务(类似于并行事务)。

您提到的事务属性应该在您的场景中按预期工作;如果对EJB2的调用成功,它将自行提交,因为它需要新的。不过,在这种情况下,如果在EJB2调用之前弹出一个未经处理的异常,那么它甚至可能不会被调用,从而给人一种一切都在回滚的印象


如果不是这样,还可以通过注入EJBContext并调用context.setRollbackOnly()来控制EJB1中的事务。这将标记当前事务,使其在完成时回滚,并按您的预期工作。

我无法确认您的声明:

它工作得很好,新的事务被创建。问题在于回滚情况:当EJB2失败时,只有它的事务被回滚,正如预期的那样。当EJB1失败时,所有这些都将回滚,正如预期的那样,但不是我所需要的

我的EJB1方法没有任何注释(我想应该默认为
必需的
),EJB2方法用
@TransactionAttribute(TransactionAttributeType.REQUIRES\u NEW)
注释

EJB1正在调用EJB2。在EJB2中,我保留了一个实体,并保留了该方法。回到EJB1中,我通过抛出异常导致回滚最后,EJB2的更改仍然存在,尽管EJB1肯定已经被回滚。


此外,在EJB2离开后,您已经可以在数据库中看到提交的更改(使用断点暂停了EJB1的执行)。

您是否可以在EJB1上再创建一层?我想说的是,您应该在与顶层不同的事务中协调对EJB1和EJB2的调用。@Sandip感谢您的回复。我得到了你的想法,简单而且肯定能解决我的问题,但我还没想到。。。它将对我现在的代码产生巨大的影响。但我仍然好奇CMT是否有任何解决方案,哈哈。。。再次感谢,我将在寻找IDIEA的同时研究实施您的ideia的影响。嗨,Fabio,谢谢您的回复。我想你不明白我的问题,或者我不完全理解你说的话。我需要的是:调用EJB1,然后用新事务调用EJB2。EJB2毫无例外地返回,它的事务“准备提交”,只等待EJB1提交。但是如果EJB1失败并回滚,它也会回滚我的EJB2事务,我不希望这样,我希望EJB2的事务仍然提交。我知道我的英语很混乱,所以再次感谢你的努力。我一直在寻找你所说的,我开始认为我的概念是错误的。是这样吗?实际上,REQUIRES_NEW将创建一个完整的分离事务,并且在“祖先”事务回滚时不会回滚。这是我的错吗?我的观念?再次感谢……你说得对;当您使用“requiresnew”创建事务时,它将在自己的事务上下文中运行,并且独立于调用它的人。所以回到这个场景中,您的EJB1将打开一个新事务,因为它是“必需的”(加入一个现有事务或创建一个新事务(如果不存在)。当代码到达EJB2上的方法调用时,该方法调用将在完全不同的事务中运行,因为“requiresnew”;这意味着如果EJB2回滚,它将不会影响EJB1上的事务。这里的一个关键概念是您的EJB方法如何调用join或运行到不同的事务中。在您的EJB2“Requires new”方法中,如果您调用另一个具有“Required”属性的EJB,它将回滚,这将影响与第三个EJB和EJB2的事务,因为它已加入EJB2的事务?如果EJB2调用成功运行后EJB1失败?EJB2事务仍然提交?正确的?如果这是真的,我将打开关于如何在事务lol上创建“保存点”的其他问题。。。我只是认为这就是解决这个问题的方法,呵呵,谢谢你的回答,但那几乎是一年前的事了,我不确定那件事发生了什么,即使我的问题假设是错的。也许我错了,真的不记得了。。。对不起…不介意,我只是想澄清一下,以防其他人看到这个网站,并有同样的问题。的确,这就是我来这里的原因
@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)