分布式事务中的合法回滚:可能吗?

时间:2017-07-18 07:03:03

标签: java-ee transactions ejb websphere ejb-3.0

我有一个参与全局事务的EJB。 有一部分代码,如果失败,我想明确回滚,虽然我不希望整个事务失败。

由于在CMT中禁止回滚,我创建了一个BMT并尝试了以下代码:

connection.setAutoCommit(false);
Savepoint sp= connection.setSavepoint();
try{
    //my code editing DB that could possibly fail
}catch(SomeException ex){
    connection.rollback(sp);
}

这样我只是撤消我的本地数据库修改,但我也没有将此失败传播到外部。无论如何,这个程序失败了:

  

"在分布式事务中禁止使用Savepoint"

有没有其他方法可以解决这个问题?

2 个答案:

答案 0 :(得分:2)

您可以使用带有@TransactionAttribute(REQUIRES_NEW)注释的第二个EJB来使用CMT,您可以在其中放置可能失败的代码。您必须从其他EJB调用此EJB。

容器为代码创建一个新事务,如果失败则将回滚。

答案 1 :(得分:1)

事务上下文不会传播到BTM。您的bean也不会成为全局事务的一部分。因此,当您的全局事务失败时,您的更改仍可以提交。

我不熟悉websphere设置但我会重新检查连接是否正确。我希望注入BTM还是以某种方式从CMT传递连接?如果连接设置为支持jta / global事务,我可以尝试检查容器配置。 或者,在开始使用连接之前,您是否启动了一些UserTransaction.begin()? 如果这样做仍然无法解决您的问题。

适合您使用嵌套事务,但Java EE不支持它们。就好像WebShere有一些特定于提供者的方式来运行它们(我不知道它的能力)。

然后最简单的方法是使用CMT REQUIRES_NEW,但即使全局事务已回滚,它也有提交db更改的缺点。

可能需要更改某些应用程序。