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