如果我们在使用@Transactional
注释注释的方法中捕获异常,如果发生任何异常,它会回滚吗?
@Transactional(readOnly = false, propagation = Propagation.REQUIRED, rollbackFor=Throwable.class)
public void yearEndProcess() {
try {
// try block
} catch (Throwable throwable) {
// catch block
}
}
答案 0 :(得分:19)
例如
class A{
@Transactional
public Result doStuff(){
Result res = null;
try {
// do stuff
} catch (Exception e) {
}
return res ;
}
}
如果方法doStuff
中存在例外情况,则交易不会回滚。
To rollback the exception programmatically
,我们可以执行以下操作。
陈述性方法
@Transactional(rollbackFor={MyException1.class, MyException2.class, ....})
public Result doStuff(){
...
}
程序化回滚
你需要从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.
答案 1 :(得分:2)
您希望阅读this
集成交易管理。您可以通过@Transactional注释或通过在XML配置文件中显式配置事务AOP建议,使用声明性,面向方面编程(AOP)样式方法拦截器来包装ORM代码。在这两种情况下,都会为您处理事务语义和异常处理(回滚等)。如下所述,在资源和事务管理中,您还可以交换各种事务管理器,而不会影响与ORM相关的代码。例如,您可以使用两种方案中可用的相同完整服务(例如声明性事务)在本地事务和JTA之间进行交换。此外,与JDBC相关的代码可以与您用于执行ORM的代码进行事务性完全集成。这对于不适合ORM的数据访问很有用,例如批处理和BLOB流,它仍然需要与ORM操作共享常见事务。
答案 2 :(得分:2)
来自春季参考文档
Spring建议您只注释具体类(以及具体类的方法) 使用@Transactional注释,而不是注释接口。你当然可以 将@Transactional注释放在接口(或接口方法)上,但这可行 只有在您使用基于接口的代理时才会如此期望。 Java的事实 如果您使用基于类的代理,那么注释不会从接口继承 (proxy-target-class =" true")或基于编织的方面(mode =" aspectj"),然后 代理和编织基础设施无法识别交易设置 对象不会被包装在事务代理中,这将是非常糟糕的。
在代理模式(默认设置)下,只有通过代理进入的外部方法调用 截获。这意味着自调用实际上是目标对象调用中的一个方法 目标对象的另一种方法,即使是在运行时也不会导致实际的事务 调用的方法用@Transactional标记。
然后使用@Transaction,默认行为是任何RuntimeException都会触发回滚,而任何已检查的Exception都不会。然后,对于已检查的Exception Throwable
,您的事务将回滚所有RuntimeException答案 3 :(得分:-1)
你已经在@Transactional注释中提到了属性:rollbackFor = Throwable.class。
因此,对于任何类型的异常事务都将被回滚。