MySQL 事务
事务的特性(ACID)
- 原子性(Atomicity)
undo log (MVCC)
事务是一个完整的操作,事务的各元素是不可分割的,所有元素必须作为一个整体提交或回滚,如果事务中的任何元素失败,整个事务将失败 - 一致性(Consistency)
最核心和最本质的要求
当事务完成时,数据必须处于一致状态。
也就是说在事务开始之前,数据库中存储的数据处于一致状态,在正在进行的事务中,数据可能处于不一致的状态,如数据可能有部分被修改,但当事务成功完成时,数据必须再次回到已知的一致状态。
通过事务对数据所做的修改不能损坏数据,或者说事务不能使数据存储处于不稳定的状态 - 隔离性(Isolation)
锁、MVCC(多版本并发控制)
对数据进行修改的所有并发事务是彼此隔离的,这表明事务必须是独立的,它不应以任何方式依赖于或影响其他事务(修改数据的事务可以在另一个使用相同数据的事务开始之前/结束之后访问这些数据) - 持久性(Durability)
redo log
事务的持久性指不管系统是否发生了故障,事务的处理结果都是永久的,即一旦事务被提交,事务对数据库所做的任何变动都会被永久保留在数据库中
事务隔离级别要解决的问题
- 脏读: 指的是读到其他事务未提交的数据,未提交意味着这些数据有可能回滚,即可能最终不会存到数据库中。读到了并不一定最终存在的数据就叫脏读
- 不可重复读: 对比可重复读,指同一事务内,不同的时刻读到的同一批数据可能是不一样的,可能受到其他事务的影响,比如其他事务更改了这一批数据并进行了提交。通常针对数据更新操作
可重复读: 在一个事务内,最开始读到的数据和事务结束前任意时刻读到的同一批数据都是一致的,通常针对数据更新操作 - 幻读: 针对数据插入操作。假设事务 A 对某些行的内容进行了更改,但是还未提交,此时事务 B 对这些行的数据进行了更改,并在事务 A 提交之前先提交了,此时在事务 A 中进行查询,会发现刚刚的更改似乎对某些行没有起作用
事务隔离级别
SQL 标准定义了四种隔离级别,MySQL 全部支持
- 读未提交(READ UNCOMMITTED)
事务的修改即使没有提交,对其他事务也是可见的。 - 读已提交(READ COMMITTED)
事务读取已提交的数据,大多数数据库的默认隔离级别。 - 可重复读(REPEATABLE READ)
MySQL 的默认隔离级别,解决了脏读的问题,同时也保证了同一个事务多次读取同样的记录是一致的,但这个级别仍会出现幻读情况 - 可串行化(SERIALIZABLE)
最高的隔离级别,完全服从 ACID 的隔离级别。所有的事务依次逐个执行,这样事务之间完全不可能产生干扰,可以完全防止脏读、不可重复读、幻读
从上往下隔离强度逐渐增强,性能逐渐变差。
事务隔离级别的目的就是解决脏读、不可重复读、幻读等问题,以下为解决程度。
只有串行化解决了所有问题,其他三个隔离级别各有缺陷- 读未提交(READ UNCOMMITTED)