长沙的网站建设,蓝田县建设局网站,微信h5爆点游戏源码,医院网站建设方案青岛卓信此文章为笔记#xff0c;为阅读其他文章的感受、补充、记录、练习、汇总#xff0c;非原创#xff0c;感谢每个知识分享者。 文章目录 1、异常被捕获后没有抛出2、抛出非运行时异常3、方法内部直接调用4、新开启一个线程5、注解到private方法上6、数据库本身不支持7、事务传…此文章为笔记为阅读其他文章的感受、补充、记录、练习、汇总非原创感谢每个知识分享者。 文章目录 1、异常被捕获后没有抛出2、抛出非运行时异常3、方法内部直接调用4、新开启一个线程5、注解到private方法上6、数据库本身不支持7、事务传播属性设置错误 Transactional是一种基于注解管理事务的方式spring通过动态代理的方式为目标方法实现事务管理的增强。 Transactional使用起来方便但也需要注意引起Transactional失效的场景本文总结了七种情况下面进行逐一分析。
1、异常被捕获后没有抛出
当异常被捕获后并且没有再抛出那么deleteUserA是不会回滚的。
Transactional
public void deleteUser() {userMapper.deleteUserA();try {int i 1 / 0;userMapper.deleteUserB();} catch (Exception e) {e.printStackTrace();}
}2、抛出非运行时异常
异步虽然抛出了但是抛出的是非RuntimeException类型的异常依旧不会生效。
Transactional
public void deleteUser() throws MyException{userMapper.deleteUserA();try {int i 1 / 0;userMapper.deleteUserB();} catch (Exception e) {throw new MyException();}
}如果指定了回滚异常类型为Exception那么就可以回滚非RuntimeException类型异常了。
Transactional(rollbackFor Exception.class)3、方法内部直接调用
如果先调用deleteUser()那么deleteUserA()是不会回滚的其原因就是Transactional根本没生成代理如果直接调用deleteUser2()那么没问题deleteUserA()会回滚。
public void deleteUser() throws MyException{deleteUser2();
}Transactional
public void deleteUser2() throws MyException{userMapper.deleteUserA();int i 1 / 0;userMapper.deleteUserB();
}修改方式把当前类自己注入一下调用即可。
Service
public class UserService {Autowiredprivate UserMapper userMapper;//自己注入自己AutowiredUserService userService;public void deleteUser() throws MyException{userService.deleteUser2();}Transactionalpublic void deleteUser2() throws MyException{userMapper.deleteUserA();int i 1 / 0;userMapper.deleteUserB();}
}4、新开启一个线程
如下的方式deleteUserA()也不会回滚因为spring实现事务的原理是通过ThreadLocal把数据库连接绑定到当前线程中新开启一个线程获取到的连接就不是同一个了。
Transactional
public void deleteUser() throws MyException{userMapper.deleteUserA();try {//休眠1秒保证deleteUserA先执行Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}new Thread(() - {int i 1/0;userMapper.deleteUserB();}).start();
}5、注解到private方法上
idea直接会给出提示Methods annotated with ‘Transactional’ must be overridable 原理很简单private修饰的方式spring无法生成动态代理。
Transactional
private void deleteUser() throws MyException{userMapper.deleteUserA();int i 1/0;userMapper.deleteUserB();
}6、数据库本身不支持
mysql数据库必须设置数据库引擎为InnoDB。
7、事务传播属性设置错误
注意传播属性的设置比如设置了PROPAGATION_NOT_SUPPORIED以非事务的方式执行如果当前有事务则把当前事务挂起。