2017-07-18 48 views
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); 
} 

这样,我只是撤消我的本地数据库修改,但我也不会传播这种故障转移到外面。反正这程序失败为:

“保存点在分布式事务中禁止”有没有办法解决这个问题的另一种方法?

回答

1

事务上下文不会传播到BTM。你的bean也不会成为全局事务的一部分。所以,如果全局事务失败,您的更改仍可能被提交。

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

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

然后,最简单的方法是使用CMT REQUIRES_NEW,但它的缺点是即使全局事务被回滚也会提交数据库更改。

也许需要一些应用程序设计变更。

2

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

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

+0

如果新事务有效,新事务也会提交。请注意,新交易与第一笔交易无关,并且如果某件事使第一笔交易回滚(出于另一原因),则新笔交易仍将承诺。 – kaczyns