嵌套事务及事务不起作用的问题

31次阅读

共计 1261 个字符,预计需要花费 4 分钟才能阅读完成。

代码方法示例
@Transactional
public void saveAA() {
    try {
    // 方法 A 第一次更新数据
mapper.save();
// 调用方法 B 更新数据
this.saveBB();
    } catch (Exception e) {
throw new RuntimeException();
     }
}
@Transactional
public void saveBB(){
try {
// 方法 B 第一次更新数据
mapper.save();

int i = 100/0;
// 方法 B 第二次更新数据
mapper.save();
} catch (Exception e) {
//e.printStackTrace();
throw new RuntimeException();
}
}
说明:
 
让事务起作用,遇到错误进行回滚,应该注意的事项:
第一种情况:同一个类中 一个方法无嵌套方法
 1、如果方法名上加上 @Transactional 注解,方法内不要用 try catch;如果必须要用 try catch,则 catch 中必须用 throw new RuntimeException()。否则事务不起作用。
第二种情况:同一个类中 方法 A 嵌套方法 B
1、方法 A 有 @Transactional,方法内都没有 try catch,事务起作用。
2、方法 A 有 @Transactional 和 try catch,并且 catch 中用 throw new RuntimeException(),事务起作用。
第三种情况:不同类中,方法 C 嵌套方法 B
1、方法 B 上加上 @Transactional 注解,方法内不要用 try catch;如果必须要用 try catch,则 catch 中必须用 throw new RuntimeException()。否则方法 B 的事务不起作用。
2、方法 C 上加上 @Transactional 注解,方法内不要用 try catch;如果必须要用 try catch,则 catch 中必须用 throw new RuntimeException(),此时方法 B 怎么写都行。否则方法 C 的事务不起作用。
 
总结
1、要想事务起作用,必须是主方法名上有 @Transactional 注解,方法体内不能用 try catch;如果用 try catch,则 catch 中必须用 throw new RuntimeException();
2、@Transactional 注解应该只被应用到 public 方法上,不要用在 protected、private 等方法上,即使用了也将被忽略,不起作用。这是由 Spring AOP 决定的。
3、只有来自外部的方法调用才会呗 AOP 代理捕捉,类内部方法调用类内部的其他方法,子方法并会不引起事务行为,即使被调用的方法上使用有 @Transactional 注解。
4、类内部方法调用内部的其他方法,被调用的方法体中如果有 try catch,则 catch 中必须用 throw new RuntimeException(),否则即使主方法上加上 @Transactional 注解,如果被调用的子方法出错也不会抛出异常,不会引起事务起作用。

正文完
 0