本系列包含:
1.什么是事务?
一组原子性的 SQL 语句,或者说一个独立的工作单元。(由一个有限的数据库操作序列构成,这些操作要么全部执行,要么全部不执行,是一个不可分割的工作单位。)
- 事务拥有 ACID(原子性、一致性、隔离性、持久性)四个特性。
- 事务通过 日志文件(undo log 和 redo log)实现可靠性。
- 事务通过 隔离级别 实现并发处理。
- 实现事务功能的三个技术:日志文件(redo log 和 undo log)、锁技术、MVCC。
2.redo log 和 undo log
- redo log 是用来恢复数据的,用于保障已提交事务的持久化特性。
- undo log 是用来回滚数据的,用于保障未提交事务的原子性。
3.读写锁实现了事务的隔离性
- shared lock:共享锁、读锁。
- exclusive lock:排他锁,写锁。
4.MVCC
MVCC(MultiVersion Concurrency Control),中文叫 多版本并发控制,它是通过读取历史版本的数据,来降低并发事务冲突,从而提高并发性能的一种机制。它的实现依赖于 隐式字段、undo日志、快照读&当前读、Read View。
- InnoDB 的 MVCC ,是通过在每行记录的后面保存两个隐藏的列来实现的。这两个列, 一个保存了行的创建时间,一个保存了行的过期时间, 当然存储的并不是实际的时间值,而是系统版本号。
- MVCC 在 MySQL 中的实现依赖的是 undo log 与 Read View。undo log 中记录某行数据的多个版本的数据。Read View 用来判断当前版本数据的可见性。
- 快照读:读取的是记录数据的可见版本(有旧的版本),不加锁,普通的 select 语句都是快照读。
- 当前读:读取的是记录数据的最新版本,显示加锁的都是当前读。
- Read View 就是事务执行快照读时,产生的读视图。事务执行快照读时,会生成数据库系统当前的一个快照,记录当前系统中还有哪些活跃的读写事务,把它们放到一个列表里。Read View主要是用来做可见性判断的,即判断当前事务可见哪个版本的数据 ~
5.实现事务采取了哪些技术以及思想?
- 原子性:使用 undo log,从而达到回滚。
- 持久性:使用 redo log,从而达到故障后恢复。
- 隔离性:使用锁以及 MVCC,运用的优化思想有读写分离,读读并行,读写并行。
- 一致性:通过回滚,以及恢复,和在并发环境下的隔离做到一致性。
6.并发事务存在哪些问题?
- 脏读:事务 A、B 交替执行,事务 A 被事务 B 干扰到了,因为事务 A 读取到事务 B 未提交的数据。
- 不可重复读:在事务 A 范围内,两个相同的查询,读取同一条记录,却返回了不同的数据。
- 幻读:事务 A 查询一个范围的结果集,另一个并发事务 B 往这个范围中 插入 / 删除 了数据,并静悄悄地提交,然后事务 A 再次查询相同的范围,两次读取得到的结果集不一样了。
7.既然并发事务存在脏读、不可重复、幻读等问题,InnoDB 实现了哪几种事务的隔离级别应对呢?
- 读未提交(Read Uncommitted,RU):在读未提交隔离级别下,一个事务会读到其他事务未提交的数据的,即存在脏读问题。事务 B 都还没 commit 到数据库呢,事务 A 就读到了,感觉都乱套了。实际上,读未提交是隔离级别最低的一种。
- 读已提交(Read Committed,RC):为了避免脏读,数据库有了比读未提交更高的隔离级别,即读已提交。但是,隔离级别设置为读已提交的时候,还会存在不可重复读的并发问题。
- 可重复读(Repeatable Read,RR):解决了不可重复读的问题,但没有完全解决存在的幻读问题。
- 串行化(Serializable):当数据库隔离级别设置为
serializable
的时候,事务 B 对表的写操作,在等事务 A 的读操作。其实,这是隔离级别中最严格的,读写都不允许并发。它保证了最好的安全性,性能却是个问题。
8.MySQL 是怎样实现上述四种不同的隔离级别的呢?
MySQL 使用不同的 锁策略 / MVCC 来实现四种不同的隔离级别。RC、RR 的实现原理跟 MVCC 有关,RU 和 Serializable 的实现原理跟锁有关。
- 读未提交,采取的是读不加锁原理。事务读不加锁,不阻塞其他事务的读和写。事务写阻塞其他事务写,但不阻塞其他事务读;
- 串行化中,读加共享锁,写加排他锁,读写互斥。如果有未提交的事务正在修改某些行,所有 select 这些行的语句都会阻塞。
- RC 跟 RR 隔离级别,最大的区别就是:RC 每次读取数据前都生成一个 ReadView,而 RR 只在第一次读取数据时生成一个 ReadView。
参考资料
【1】一文彻底读懂 MySQL 事务的四大隔离级别
【2】图解 mysql 事务实现原理