spring事务失效场景
2023-06-08 22:01:46 0 举报
AI智能生成
Spring事务失效场景通常发生在以下几种情况:1. 方法没有被Spring管理,即没有使用@Transactional注解;2. 异常类型不符合预期,例如在捕获了RuntimeException类型的异常后,事务仍然会回滚;3. 数据库引擎不支持事务,例如MyISAM;4. 手动提交事务或者在事务外部修改了数据;5. 多线程环境下,同一个事务被多个线程同时访问。
作者其他创作
大纲/内容
访问权限问题
private
default
protected
方法用final修饰
@Service<br>public class EmpService {<br> @Transactional<br> public final void add(UserModel userModel){<br> saveData(userModel);<br> }<br>}
因为spring事务底层是用了aop,用了jdk的动态代理或者cglb的动态代理,会帮我们生成代理类,在代理类中实现事务功能。<br><br>如果某个方法被final修饰了,那么在代理类中,就无法重新该方法,而添加事务功能
多线程管理
@Service<br>public class EmpService {<br> @Autowired<br> private OrderService orderService;<br> @Transactional<br> public void add(UserModel userModel){<br> <br> new Thread(()->{<br> orderService.updateSataus();<br> }).start();<br> }<br> }<br> @Service<br>public class OrderService{<br> @Transactional<br> public void updateSataus(){<br> System.out.println("======================");<br> }<br> }
事务保存在当前线程的treadlocal中,如果是多线程的话就是多个threadlocal,线程之间相互隔离,自然多线程事务是失效的
手动抛了别的异常
@Service<br>public class EmpService {<br> @Transactional<br> public void add(UserModel userModel) throws Exception {<br> try {<br> saveData(userModel);<br> updateSataus(userModel);<br> } catch (Exception e) {<br> <br> throw new Exception(e);<br> }<br> }<br> <br>}
因为Spring事务,默认情况下只会回滚RuntimeException(运行时异常)和Error(错误),对于普通的非运行时异常,它不会回滚
数据库不支持事务
inodb支持事务
myisam不支持事务
类未被spring容器管理
public class EmpService {<br> @Transactional<br> public void add(UserModel userModel){<br> saveData(userModel);<br> updateSataus(userModel);<br> }<br> }
事务是基于spring容器管理的,如果没有被spring容器管理,事务自然会失效
直接调用内部方法
@Service<br>public class EmpService {<br> @Transactional<br> public void add(UserModel userModel){<br> saveData(userModel);<br> updateSataus(userModel);<br> }<br> @Transactional<br> public void updateSataus(UserModel userModel){<br> doSomething();<br> }<br>}
由上可知:在事务方法add可知,它直接调用了updateStatus方法,由2可知:方法拥有事务的能力是因为spring aop中生成了代理对象,但是直接调用updateStatus方法不会直接生成事务。但是可以直接将该类直接注入进来,比如
@Service<br>public class EmpService {<br> private EmpService empService;<br> @Transactional<br> public void add(UserModel userModel){<br> saveData(userModel);<br> empService.updateSataus(userModel);<br> }<br> @Transactional(rollbackFor = Exception.class)<br> public void updateSataus(UserModel userModel){<br> doSomething();<br> }<br>}
调用本类的方法(this代表了是本类对象调用,而不是从容器中获取到代理对象去调用)
事务未开启
如果是springBoot项目,那么是事务默认是开启的,但如果是spring项目,需要xml配置
方法的传播类型不支持事务
如果事务的传播特性设置错了,事务也会失效。如下:propagation = Propagation.NEVER这种类型的传播特性不支持事务,如果有事务会抛出异常。<br><br>目前只有这三种传播特性才会创建新事物:REQUIRED、REQUIRES_NEW、NESTED
@Service<br>public class EmpService {<br> @Transactional(propagation = Propagation.NEVER)<br> public void add(UserModel userModel){<br> saveData(userModel);<br> updateSataus(userModel);<br> }<br> <br>}
自己吞了异常没有交给事务
@Service<br>public class EmpService {<br> @Transactional<br> public void add(UserModel userModel){<br> try {<br> saveData(userModel);<br> updateSataus(userModel);<br> } catch (Exception e) {<br> e.printStackTrace();<br> }<br> }<br> }
事务不会回滚,最常见的问题是:开发者在代码中手动try...catch了异常。如下:
0 条评论
下一页