一、基础事务回顾
在MySQL的众多存储引擎中,只有InnoDB支持事务,所有这里说的事务隔离级别指的是InnoDB下的事务隔离级别。
事务隔离级别,以及导致的问题
隔离级别 | 定义 | 脏读 | 幻读 | 不可重复度 |
读未提交 | 一个事务可以读取到另一个事务未提交的修改。这会带来脏读、幻读、不可重复读问题。 | √ | √ | √ |
读已提交 | 一个事务只能读取另一个事务已经提交的修改。其避免了脏读,但仍然存在不可重复读和幻读问题。 | × | √ | √ |
可重复读 | 同一个事务中多次读取相同的数据返回的结果是一样的。其避免了脏读和不可重复读问题,但幻读依然存在。 | × | × | √ |
串行化 | 事务串行执行。避免了以上所有问题。 | × | × | × |
在MySQL中,默认的隔离级别是REPEATABLE-READ(可重复读),并且解决了幻读问题。简单的来说,mysql的默认隔离级别解决了脏读、幻读、不可重复读问题。
不可重复读重点在于update和delete,而幻读的重点在于insert插入。
二、mvcc定义
MVCC的全称是“多版本并发控制”。这项技术使得InnoDB的事务隔离级别下执行一致性读操作有了保证,即为了查询一些正在被另一个事务更新的行,并且可以看到它们被更新之前的值。这是一个可以用来增强并发性的强大的技术,因为这样的一来的话查询就不用等待另一个事务释放锁。
三、增删查改
在InnoDB中,给每行增加两个隐藏字段来实现MVCC,一个用来记录数据行的创建时间,另一个用来记录行的过期时间(删除时间)。在实际操作中,存储的并不是时间,而是事务的版本号,每开启一个新事务,事务的版本号就会递增。
对于mysql数据库默认的隔离级别(REPEATABLE READ)下,增删查改变成了这样
SELECT | 读取创建版本小于或等于当前事务版本号,并且删除版本为空或大于当前事务版本号的记录。这样可以保证在读取之前记录是存在的。 |
INSERT | 将当前事务的版本号保存至行的创建版本号 |
UPDATE | 新插入一行,并以当前事务的版本号作为新行的创建版本号,同时将原记录行的删除版本号设置为当前事务版本号 |
DELETE | 将当前事务的版本号保存至行的删除版本号 |
其中:快照读和当前读
快照读:读取的是快照版本,也就是历史版本
当前读:读取的是最新版本
普通的SELECT就是快照读,而UPDATE、DELETE、INSERT、SELECT ... LOCK IN SHARE MODE、SELECT ... FOR UPDATE是当前读。
四、针对增删改查的实例
参考博客:mysql的MVCC(多版本并发控制)
五、补充知识
1.redo log、undo log和bin log三者区别
六、参考