事务的基本特性及隔离级别
PPG007 ... 2021-12-28 About 2 min
# 事务的基本特性及隔离级别
# ACID
- 原子性
- 一致性:数据库总是从一个一致性状态转换到另外一个一致性的状态
- 隔离性:一个事务在最终提交前对其他事务不可见
- 持久性:事务一旦提交,所做的修改会永久的保存到数据库中
# 四个隔离级别
- 读未提交:
可能会读到其他事务未提交的数据,也叫脏读。
- 读已提交:
两次读取结果不同,叫做不可重复读。
不可重复读解决了脏读的问题,只会读取已经提交的事务
- 可重复读:
MySQL 默认级别,每次读取结果都一样,但有可能产生幻读。
- 串行:
一般不使用,会给每一行读取的数据加锁,导致大量超时和锁竞争问题。
# ACID 由何保证
- 原子性:由 undo log 保证,记录了要回滚的日志信息,事务回滚是撤销已经执行成功的 SQL。
- 一致性:由其他三大特性保证、程序代码要保证业务上的一致性。
- 隔离性:由 MVCC 来保证。
- 持久性:由内存+redo log 来保证,MySQL 修改数据同时要在内存和 redo log 记录这次操作,宕机时可以从 redo log 恢复。
# MVCC
多版本并发控制:读取数据时通过一种类似快照的方式将数据保存下来,这样读锁和写锁就不冲突了,不同的事务会话会看到自己特定版本的数据。
MVCC 只在读已提交和可重复读两个隔离级别下工作。
开始事务时创建 readview,readview 维护当前活动的事务 ID,即未提交的事务 ID,排序生成一个数组,访问数据,获取数据中的事务 ID,获取的是事务ID最大的记录,对比 readview:
- 如果在 readview 左边,说明该事务已提交,可以访问。
- 如果在 readview 右边或者就在 readview 中间,说明该事务未提交,不可以访问,根据 roll_pointer 取上一版本重新对比。
读已提交级别下的事务在每次查询的开始都会生成一个独立的 ReadView,而可重复读级别则在第一次读的时候生成一个 ReadView,之后读都复用之前的 ReadView。