Spring第六篇-事务
什么是事务
- 事务是数据库的概念,事务代表了一组数据库操作,数据库操作要么全部成功,要么全部失败。
- 事务有几个特征
- 原子性
- 一致性
- 隔离性
- 持久性
具体事务可以看我之前的数据库文章
03 | 事务
Spring 事务操作
事务的配置
<!-- 开启组件扫描-->
<context:component-scan base-package="springDemo"></context:component-scan>
<!-- 注入datasource-->
<bean class="com.alibaba.druid.pool.DruidDataSource" id="dataSource">
<property name="url" value="jdbc:mysql://localhost:3306/hello"></property>
<property name="username" value="root"></property>
<property name="password" value="root"></property>
<property name="driverClassName" value="com.mysql.cj.jdbc.Driver"></property>
</bean>
<!-- 配置jdbcTemplate-->
<bean class="org.springframework.jdbc.core.JdbcTemplate" id="jdbcTemplate">
<property name="dataSource" ref="dataSource"></property>
</bean>
<!-- 配置事务管理器-->
<bean class="org.springframework.jdbc.datasource.DataSourceTransactionManager" id="dataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean>
<!-- 开启事务注解-->
<tx:annotation-driven transaction-manager="dataSourceTransactionManager"></tx:annotation-driven>
在 Service 类上加上@Transactional 注解
- 无异常则直接提交
- 有异常则全部回滚
事务的传播行为
简单的理解就是多个事务方法相互调用时,事务如何在这些方法间传播。
举个栗子,方法 A 是一个事务的方法,方法 A 执行过程中调用了方法 B,那么方法 B 有无事务以及方法 B 对事务的要求不同都会对方法 A 的事务具体执行造成影响,同时方法 A 的事务对方法 B 的事务执行也有影响,这种影响具体是什么就由两个方法所定义的事务传播类型所决定。
** 在这里要做一个重要提示:Spring 中事务的默认实现使用的是 AOP,也就是代理的方式,如果大家在使用代码测试时,同一个 Service 类中的方法相互调用需要使用注入的对象来调用,不要直接使用 this.方法名来调用,this.方法名调用是对象内部方法调用,不会通过 Spring 代理,也就是事务不会起作用**
REQUIRED(Spring 默认的事务传播类型)
如果当前没有事务,则自己新建一个事务,如果当前存在事务,则加入这个事务
SUPPORTS
当前存在事务,则加入当前事务,如果当前没有事务,就以非事务方法执行
MANDATORY
当前存在事务,则加入当前事务,如果当前事务不存在,则抛出异常。
REQUIRES_NEW
创建一个新事务,如果存在当前事务,则挂起该事务。
NOT_SUPPORTED
始终以非事务方式执行,如果当前存在事务,则挂起当前事务
可以理解为设置事务传播类型为 NOT_SUPPORTED 的方法,在执行时,不论当前是否存在事务,都会以非事务的方式运行
NEVER
不使用事务,如果当前事务存在,则抛出异常
很容易理解,就是我这个方法不使用事务,并且调用我的方法也不允许有事务,如果调用我的方法有事务则我直接抛出异常
NESTED
如果当前事务存在,则在嵌套事务中执行,否则 REQUIRED 的操作一样(开启一个事务)
这里需要注意两点:
- 和 REQUIRES_NEW 的区别
REQUIRES_NEW 是新建一个事务并且新开启的这个事务与原有事务无关,而 NESTED 则是当前存在事务时(我们把当前事务称之为父事务)会开启一个嵌套事务(称之为一个子事务)。
在 NESTED 情况下父事务回滚时,子事务也会回滚,而在 REQUIRES_NEW 情况下,原有事务回滚,不会影响新开启的事务。 - 和 REQUIRED 的区别
REQUIRED 情况下,调用方存在事务时,则被调用方和调用方使用同一事务,那么被调用方出现异常时,由于共用一个事务,所以无论调用方是否 catch 其异常,事务都会回滚
而在 NESTED 情况下,被调用方发生异常时,调用方可以 catch 其异常,这样只有子事务回滚,父事务不受影响
事务的隔离级别
MySQL 的事务隔离级别有四个
- 读未提交
- 读已提交
- 可重复读
- 串行化
具体看 Mysql 笔记
spring 事务-xml 方式
配置事务管理器
配置通知
配置切入点和切面
spring 事务-注解方式
test
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 小周の代码之路!
评论