什么是事务
事务是数据库操作的最基本单元,逻辑上一组操作,要么都成功,如果有一个失败所有操作都失败。
- 要么都成功,要么都失败
- 事务在项目开发中,十分的重要,涉及到数据的一致性问题,不能马虎
- 确保完整性和一致性
事务ACID原则:
- 原子性:要么都成功,要么都失败
- 一致性:事务前后数据的完整性必须保持一致
- 隔离性:事务的隔离性是多个用户并发访问数据库时,数据库为每一个用户开启的事务,不能被其他事务的操作数据所干扰,多个并发事务之间要相互隔离
- 多个业务可能操作多个资源,防止数据损坏。
- 持久性:指一个事务一旦被提交,它对数据库中数据的改变就是永久性的,接下来即使数据库发生故障也不应该对其有任何影响
- 事务一旦提交,无论系统发生什么问题,结果都不会被影响。数据被持久化的写到存储器中
Spring事务操作
-
事务添加到 JavaEE 三层结构里面 Service 层(业务逻辑层)
-
在 Spring 进行事务管理操作
- 有两种方式:编程式事务管理和声明式事务管理(使用)
-
声明式事务管理
- 基于注解方式(使用
- 基于 xml 配置文件方式
-
在 Spring 进行声明式事务管理,底层使用 AOP 原理
-
Spring 事务管理 API
-
提供一个接口,代表事务管理器,这个接口针对不同的框架提供不同的实现类
-
Spring事务操作(基于注解操作声明式事务)
-
在 spring 配置文件配置事务管理器
<!-- 配置声明式事务--> <bean id="TransactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <!-- 注入数据源--> <property name="dataSource" ref="dataSource"/> </bean>
<!-- 开启事务的注解--> <tx:annotation-driven transaction-manager="TransactionManager"/>
-
在 service 类上面(或者 service 类里面方法上面)添加事务注解
- @Transactional,这个注解添加到类上面,也可以添加方法上面
- 如果把这个注解添加类上面,这个类里面所有的方法都添加事务
- 如果把这个注解添加方法上面,为这个方法添加事务
@Service("UserService")
@Transactional//配置传播行为,设置隔离级别
public class UserServiceImpl implements UserService{
}
-
运行测试:
此时,经过事务的处理,出现异常的时候,回滚到之前的操作,存款金额没发生变化。
事务操作(声明式事务管理参数配置)
-
在 service 类上面添加注解@Transactional,在这个注解里面可以配置事务相关参数
-
propagation:事务传播行为
-
多事务方法直接进行调用,这个过程中事务 是如何进行管理的
add()有事务,但是update()没有事务。如果add调用update()方法,事务该如何传播?
- Spring定义了7种类传播行为
- Spring定义了7种类传播行为
-
-
ioslation:事务隔离级别
-
事务有特性称为隔离性,多事务操作之间不会产生影响。不考虑隔离性产生很多问题
-
有三个读问题:脏读、不可重复读、幻读
-
==脏读:==一个未提交的事务读取到另一个未提交事务的数据
- A事务读取B事务尚未提交的数据,此时如果B事务发生错误并执行回滚操作,那么A事务读取到的数据就是脏数据。
-
==不可重复读:==一个未提交事务读取到另一提交事务修改数据(前后多次读取,数据内容不一致)
-
==幻读:==事务A在执行读取操作,需要两次统计数据的总量,前一次查询数据总量后,此时事务B执行了新增数据的操作并提交后,这个时候事务A读取的数据总量和之前统计的不一样,就像产生了幻觉一样,平白无故的多了几条数据,成为幻读。
- 幻读可以通过增加版本号来控制
-
解决办法:通过设置事务的隔离级别,解决读的问题。
-
-
timeout:超时时间
- 事务需要在一定时间内进行提交,如果不提交进行回滚
- 默认值是 -1 ,设置时间以秒单位进行计算
-
readOnly:是否只读
- 读:查询操作,写:添加修改删除操作
- readOnly 默认值 false,表示可以查询,可以添加修改删除操作
- 设置 readOnly 值是 true,设置成 true 之后,只能查询
-
rollbackFor:回滚
- 设置出现哪些异常进行事务回滚
-
noRollbackFor:不回滚
- 设置出现哪些异常不进行事务回滚