使用 try catch 块时的 Spring @Transactional 注释
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/25738883/
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
Spring @Transactional annotation when using try catch block
提问by Kedar Parikh
If we catch the exception in method annotated with the @Transactionalannotation, will it roll back if any exception occurs?
如果我们在使用@Transactional注解的方法中捕获异常,如果发生任何异常,它会回滚吗?
@Transactional(readOnly = false, propagation = Propagation.REQUIRED, rollbackFor=Throwable.class)
public void yearEndProcess() {
try {
// try block
} catch (Throwable throwable) {
// catch block
}
}
采纳答案by Ankur Singhal
for example
例如
class A{
@Transactional
public Result doStuff(){
Result res = null;
try {
// do stuff
} catch (Exception e) {
}
return res ;
}
}
If there is an exception in the method doStuffthe transaction isn't rolled back.
如果方法中有异常,doStuff则事务不会回滚。
To rollback the exception programmatically, we can do something like below.
To rollback the exception programmatically,我们可以做类似下面的事情。
declarative approach
声明式方法
@Transactional(rollbackFor={MyException1.class, MyException2.class, ....})
public Result doStuff(){
...
}
programmatic rollbackyou need to call it from TransactionAspectSupport.
程序回滚您需要从调用它TransactionAspectSupport。
public Result doStuff(){
try {
// business logic...
} catch (Exception ex) {
// trigger rollback programmatically
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
}
}
You are strongly encouraged to use the `declarative approach` to `rollback` if at all possible.
`Programmatic rollback` is available should only be used if you absolutely need it.
回答by Skizzo
From spring references documentation
来自弹簧参考文档
Spring recommends that you only annotate concrete classes (and methods of concrete classes) with the @Transactional annotation, as opposed to annotating interfaces. You certainly can place the @Transactional annotation on an interface (or an interface method), but this works only as you would expect it to if you are using interface-based proxies. The fact that Java annotations are not inherited from interfaces means that if you are using class-based proxies ( proxy-target-class="true") or the weaving-based aspect ( mode="aspectj"), then the transaction settings are not recognized by the proxying and weaving infrastructure, and the object will not be wrapped in a transactional proxy, which would be decidedly bad.
Spring 建议您只使用 @Transactional 注释来注释具体类(和具体类的方法),而不是注释接口。您当然可以将 @Transactional 注释放在接口(或接口方法)上,但是如果您使用基于接口的代理,这只能像您期望的那样工作。Java注解不是从接口继承的事实意味着如果你使用基于类的代理(proxy-target-class="true")或基于编织的方面(mode="aspectj"),那么事务设置是不被代理和编织基础设施识别,并且对象不会被包装在事务代理中,这绝对是糟糕的。
In proxy mode (which is the default), only external method calls coming in through the proxy are intercepted. This means that self-invocation, in effect, a method within the target object calling another method of the target object, will not lead to an actual transaction at runtime even if the invoked method is marked with @Transactional.
在代理模式下(默认),只有通过代理进入的外部方法调用才会被拦截。这意味着自调用实际上是目标对象中的一个方法调用目标对象的另一个方法,即使被调用的方法用@Transactional 标记,也不会在运行时导致实际事务。
Then with @Transaction the default behavior is that any RuntimeException triggers rollback, and any checked Exception does not. Then your transaction roll back for all RuntimeException an for the checked Exception Throwable
然后使用@Transaction,默认行为是任何 RuntimeException 都会触发回滚,而任何已检查的 Exception 都不会。然后您的事务回滚所有 RuntimeException 和已检查的 Exception Throwable
回答by Ker p pag
you would want to read this
你会想读这个
Integrated transaction management. You can wrap your ORM code with a declarative, aspect-oriented programming (AOP) style method interceptor either through the @Transactional annotation or by explicitly configuring the transaction AOP advice in an XML configuration file. In both cases, transaction semantics and exception handling (rollback, and so on) are handled for you. As discussed below, in Resource and transaction management, you can also swap various transaction managers, without affecting your ORM-related code. For example, you can swap between local transactions and JTA, with the same full services (such as declarative transactions) available in both scenarios. Additionally, JDBC-related code can fully integrate transactionally with the code you use to do ORM. This is useful for data access that is not suitable for ORM, such as batch processing and BLOB streaming, which still need to share common transactions with ORM operations.
综合事务管理. 您可以通过@Transactional 批注或通过在 XML 配置文件中显式配置事务 AOP 建议,使用声明性的、面向方面的编程 (AOP) 样式的方法拦截器包装您的 ORM 代码。在这两种情况下,事务语义和异常处理(回滚等)都会为您处理。如下所述,在资源和事务管理中,您还可以交换各种事务管理器,而不会影响您的 ORM 相关代码。例如,您可以在本地事务和 JTA 之间交换,在这两种情况下都可以使用相同的完整服务(例如声明性事务)。此外,与 JDBC 相关的代码可以与您用于执行 ORM 的代码在事务上完全集成。这对于不适合 ORM 的数据访问很有用,例如批处理和 BLOB 流,
回答by G.S.Tomar
You have already mentioned attribute:rollbackFor=Throwable.class in your @Transactional annotation.
您已经在 @Transactional 注释中提到了 attribute:rollbackFor=Throwable.class。
So, for any kind of exception transaction will be rolled back.
所以,对于任何一种异常事务都会被回滚。

