1.事务
一个数据库是一个被视为单一的工作单元的操作序列,这些操作应该要么完整的执行,要么完全不执行。事务管理是一个重要组成部分,RDBMS(关系数据库管理系统)面向企业应用程序,以确保数据的完整性和一致性。
1.1 事务四要素
- 原子性:事务应该是一个单独单元的操作,这意味着整个序列操作要么成功,要么失败;
- 一致性:事务开始前和结束后,数据库的完整性约束不能被破坏。比如A向B转账,不可能A扣了钱,而B没有收到;
- 隔离性:有时候可能会同时处理很多相同的数据集事务,每个事务应该与其它事务隔离,以防止数据被破坏;即同一时间,只允许一个事务请求同一数据,不同的事务之间彼此互不干扰;
- 持久性:事务完成后,事务对数据库所有的跟新数据被保存到数据库中们不能回滚。
使用SQL发布到数据库中的事务的简单步骤
- 使用begin transaction命令开始事务;
- 使用SQL查询语句执行各种删除、更新或插入操作;
- 如果所有的操作都成功,则执行提交操作,否则回滚所有操作。
1.2 Spring 事务的传播特性
所谓事务的传播特性就是spring管理事务的一些策略PROPAGATE(传播)
- REQUIRED:支持当前事务,如果没有当前事务,就新建一个事务;
- SUPPORTS:支持当前事务,如果没有事务,就以非事务方式执行;
- MANDATORY:支持当前事务,如果没有事务就抛出异常(mandatory 强制);
- REQUIRES_NEW:新建事务,如果存在事务,就把当前事务挂起;
- NOT_SUPPORTED:以非事务的方式执行操作,如果存在当前事务,就把事务挂起;
- NEVER:以非事务的方执行,如果当前事务存在,就抛出异常;
- NESTED:支持当前事务,如果当前事务存在,则执行一个嵌套事务,如果没有事务,就新建一个事务。
1.3 并发事务会产生的问题
举个例子,比如事务A和事务B操纵的是同一个资源,事务A有若干个子事务,事务B也有若干个子事务,事务A和事务B在高并发的情况下会出现各种各样的问题。
- **脏读:所谓脏读是指事务A读到了事务B还没有提交的数据。**比如银行取钱,事务A开启事务,此时切换到事务B,事务B开启事务–>取走100元,此时切换到事务A,事务A读取的数据肯定是数据库里面原始数据,因为事务B取走了100元并没有提交,数据库里面的余额坑定还是原始的余额,这就是脏读。
- **不可重复读:所谓不可重复读是指在一个事务里面读取了两次某个数据,但是读取的数据不一致。**还是以银行取钱为例,事务A开启事务–>查出银行卡的余额为1000元,此时切换到事务B,事务B开启事务–>事务B取走了100元,数据库里面的余额变为900元,此时切换回事务A,事务A再查一次账户余额为900元,这样对于事务A而言,在同一个事务内两次读取的账户余额不一致,这就是不可重复读。
- 幻读:所谓幻读就是指在一个事务里发下了未被操作的数据。比如学生信息,事务A开启事务–>修改所有学生当天的签到状态为false,此时切换到事务B,事务B开启事务–>事务B插入了一条学生数据,此时切换回事务A,事务A提交的时候发下了一条自己还没有修改过的数据,这就是幻读。就好像发生了幻觉一样。幻读出现的前提是并发的事务发生了插入、删除擦操作。