分布式事务中的合法回滚:可能吗?
Legit rollback in a distributed transaction: possible?
我有一个涉及全局事务的 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 is forbidden in a distributed transaction"
是否有其他方法可以解决这个问题?
您可以通过使用带有 @TransactionAttribute(REQUIRES_NEW)
注释的第二个 EJB 来使用 CMT,您可以在其中放置可能失败的代码。您必须从其他 EJB 调用此 EJB。
容器为代码创建一个新事务,如果失败将回滚。
事务上下文不会传播到 BTM。您的 bean 也不会成为全局事务的一部分。因此,当您的全局事务失败时,您的更改仍然可以提交。
我不熟悉 websphere 设置,但我会重新检查连接是否正确。我希望被注入到 BTM,或者你是否以某种方式从 CMT 传递连接?如果连接设置为支持 jta/global 事务,我可以尝试检查容器配置。
还是在开始使用连接之前启动 some UserTransaction.begin()
?
即使这有效,也不能解决您的问题。
适合您的方法是使用嵌套事务,但 Java EE 不支持它们。只是如果 WebShere 有一些提供者特定的方式如何 运行 它们(我不知道它的能力)。
那么最简单的方法就是使用 CMT REQUIRES_NEW
,但它的缺点是即使全局事务已回滚,也会提交数据库更改。
也许需要更改一些应用程序设计。
我有一个涉及全局事务的 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 is forbidden in a distributed transaction"
是否有其他方法可以解决这个问题?
您可以通过使用带有 @TransactionAttribute(REQUIRES_NEW)
注释的第二个 EJB 来使用 CMT,您可以在其中放置可能失败的代码。您必须从其他 EJB 调用此 EJB。
容器为代码创建一个新事务,如果失败将回滚。
事务上下文不会传播到 BTM。您的 bean 也不会成为全局事务的一部分。因此,当您的全局事务失败时,您的更改仍然可以提交。
我不熟悉 websphere 设置,但我会重新检查连接是否正确。我希望被注入到 BTM,或者你是否以某种方式从 CMT 传递连接?如果连接设置为支持 jta/global 事务,我可以尝试检查容器配置。
还是在开始使用连接之前启动 some UserTransaction.begin()
?
即使这有效,也不能解决您的问题。
适合您的方法是使用嵌套事务,但 Java EE 不支持它们。只是如果 WebShere 有一些提供者特定的方式如何 运行 它们(我不知道它的能力)。
那么最简单的方法就是使用 CMT REQUIRES_NEW
,但它的缺点是即使全局事务已回滚,也会提交数据库更改。
也许需要更改一些应用程序设计。