java 回滚一个@Transactional 注释的方法
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/12194891/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Rollback a @Transactional annotated method
提问by yaroslavTir
Good day. The following code:
再会。以下代码:
class A{
private B b;
@Transactional
public SomeResult doSomething(){
SomeResult res = null;
try {
// do something
} catch (Exception e) {
res = b.saveResult();
}
return res ;
}
}
@Transactional(propagation = Propagation.REQUIRES_NEW)
class B{
public SomeResult saveResult(){
// save in db
}
}
As I understand, if there is an exception in the method doSomething
the transaction isn't rolled back. And how to make that it rolled? and returned SomeResult
据我了解,如果方法中有异常,doSomething
则事务不会回滚。以及如何使它滚动?并返回 SomeResult
回答by Caio Cunha
You shouldn't call Rollback programmatically. The best way, as recommended by the docs, is to use declarative approach. To do so, you need to annotate which exceptions will trigger a Rollback.
您不应以编程方式调用 Rollback。正如docs所推荐的,最好的方法是使用声明式方法。为此,您需要注释哪些异常将触发回滚。
In your case, something like this
在你的情况下,像这样
@Transactional(rollbackFor={MyException.class, AnotherException.class})
public SomeResult doSomething(){
...
}
Take a look at the @Transaction APIand the docs about rolling back a transaction.
查看@Transaction API和有关回滚事务的文档。
If, despite the docs recommendation, you want to make a programmatic rollback, then you need to call it from TransactionAspectSupport
as already suggested. This is from the docs:
如果不顾文档的建议,您想要进行编程回滚,那么您需要TransactionAspectSupport
按照已经建议的方式调用它。这是来自文档:
public void resolvePosition() {
try {
// some business logic...
} catch (NoProductInStockException ex) {
// trigger rollback programmatically
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
}
}
There may be a architecture mistake though. If your method fails and you need to throw an exception, you shouldn't expect it to return anything. Maybe you're giving too much responsibilities to this method and should create a separated one that only model data, and throws an exception if something goes wrong, rolling back the transaction. Anyway, read the docs.
不过可能存在架构错误。如果您的方法失败并且您需要抛出异常,则不应期望它返回任何内容。也许你给这个方法太多的责任,应该创建一个单独的只对数据建模的方法,如果出现问题则抛出异常,回滚事务。无论如何,阅读文档。
回答by Jigar Parekh
get TransactionStatus using TransactionAspectSupport.currentTransactionStatus() ect transaction manager to your bean try to invoke Rollback(DefaultTransactionStatus status) in transaction manager.
使用 TransactionAspectSupport.currentTransactionStatus() 等事务管理器获取 TransactionStatus 到您的 bean 尝试在事务管理器中调用 Rollback(DefaultTransactionStatus status)。
refer to spring documentation
参考spring文档
You are strongly encouraged to use the declarative approach to rollback if at all possible. Programmatic rollback is available should you absolutely need it, but its usage flies in the face of achieving a clean POJO-based architecture.
强烈建议您尽可能使用声明式方法进行回滚。如果您绝对需要它,则可以使用编程回滚,但它的使用与实现基于 POJO 的干净架构背道而驰。