关于mysql的事务和mvcc
事务隔离级别
读未提交
- 事务a select
- 事务b update一行数据,但未提交
- 事务a再select 发现查出来的是事务b update后的
- 所以会出现脏读
读提交
- 事务a select
- 事务b update一行数据,提交
- 事务a 再select 发现查出来的是事务b提交后的(预期是事务中每一次select结果都一样)
- 所以会出现不可重复读
不可重复读
- 事务a select
- 事务b insert id=3 提交
- 事务a select看不到这条数据 但是它是存在的
- 相反事务b select可以看到
- 所以事务a 想insert id=3,发现已存在,却select不到
- 所以会出现幻读
序列化
- 每一行都加锁,顺序执行,不适合用在高并发
MVCC
select
- InnoDB的MVCC,是通过在每行后面隐藏的两列来实现的。
- 一列记录创建时间,一列记录过期/删除时间
- 不是使用日期,而是使用系统版本号
- 新事物会递增
- 所以每个事务select出的只会是<=当前版本的,就可以是开启事务前的,或者是在该事务做过修改的
INSERT
- InnoDB为插入的每一行保存当前系统版本号作为行版本号。
DELETE
- InnoDB为删除的每一行保存当前系统版本号作为行删除标识。
UPDATE
- InnoDB为插入一行新纪录,保存当前系统版本号作为行版本号,同时,保存当前系统版本号到原来的行作为行删除标识。
优点:
保存这两个额外系统版本号,使大多数读操作都可以不用加锁。这样设计使得读数据操作很简单,性能很好。
缺点:
每行纪录都需要额外的存储空间,需要做更多的行检查工作,以及一些额外的维护工作。