【重难点】【事务 02】Spring 事务
一、注解 @Transactional 的原理
Spring 本质上是对数据库事务的进一步封装,如果数据库不支持事务,那么 Spring 也无法实现事务
Spring 事务是一种声明式的事务,可以简化编程开发,只需要在启动类上添加注解驱动并配置事务管理器,然后在相关的类或者方法上添加 @Transactional 注解就可以开启并使用 Spring 事务
Spring 框架在启动时会创建 Bean 的实例对象,并且会扫描注解,如果扫描到 @Transactional 注解的类或者方法时,会根据注解的参数进行配置注入,生成指定的代理对象实现事务功能
@Transactional 有哪些参数
- 事务传播机制
- 事务隔离级别
- 超时时间:事务一定的时间内未提交会自动回滚
- 是否只读
- 异常回滚(默认为 RuntimeException)
- 异常不回滚
二、事务隔离级别
Spring 事务有五种隔离级别,分别为默认、读未提交、读已提交、可重复读和串行化
默认就是使用数据库默认的事务隔离级别,如果 Spring 事务的隔离级别与数据库的隔离级别不一致则以 Spring 事务的为准
三、事务传播机制
Spring 事务传播机制定义了 7 种类型:
REQUIRED
如果当前没有事务,就创建一个事务,如果已经存在一个事务,就加入这个事务。如果调用端发生异常,则调用端和被调用端的事务都将回滚
REQUIRED_NEW
如果当前存在事务,就将当前事务挂起,并重新创建新的事务并执行,直到新的事务提交或者回滚,才会恢复执行原来的事务
SUPPORTS
如果当前存在事务,就加入这个事务,如果当前没有事务,就以非事务的方式执行
MANDATORY
如果当前存在事务,就加入这个事务,如果当前没有事务,则会抛出异常
NOT_SUPPORTED
如果当前存在事务,就将当前事务挂起,以非事务的方式执行,如果当前没有事务,也将以非事务的方式执行
NEVER
如果当前存在事务,则抛出异常
NESTED
如果当前存在事务,则这个方法应该运行在一个嵌套事务中。外层事务回滚,内层事务也要回滚;内层事务回滚,不影响外层事务的提交
四、事务失效场景
- 数据库不支持事务
- 事务方法所在类未加载到 IOC 容器
- 事务方法没有被 public 修饰
- 调用方法和被调用方法在同一个类中,那么调用时就不会调用代理方法
- 未配置事务管理器
- 事务传播类型不支持事务
- 使用了 try-catch 导致回滚失效
- 标注了错误的异常不回滚类型