4类事务问题:
A) 修改时允许修改(丢失更新),同时修改同一条数据 (系统错误,不能接受)
B) 修改时允许读取(脏读),一个事务写,另一个事务读取到还未提交的数据(错误读取) (系统错误,不能接受)
C) 读取时允许修改(不可重复读),一个事物2次读取的数据不一致。(第2次读之前,数据被修改,这个数据是逻辑上正确的)
D) 读取时允许插入(幻读),2次读,行总数不一致。本质是多插入了。逻辑上正确的
数据对事务隔离的实现方案:
1:Read uncommit
写锁
2:Read commit
写锁
3:repeat read
读锁
4:serilizable
串行化,没有事务冲突、竞争以及乱序的问题。
####MVCC在MySQL的InnoDB中的实现
在InnoDB中,会在每行数据后添加两个额外的隐藏的值来实现MVCC,这两个值一个记录这行数据何时被创建,另外一个记录这行数据何时过期(或者被删除)。 在实际操作中,存储的并不是时间,而是事务的版本号,每开启一个新事务,事务的版本号就会递增。 在可重读Repeatable reads事务隔离级别下:
SELECT时,读取创建版本号<=当前事务版本号,删除版本号为空或>当前事务版本号。
INSERT时,保存当前事务版本号为行的创建版本号
DELETE时,保存当前事务版本号为行的删除版本号
UPDATE时,新插入一条新纪录,保存当前事务版本号为行创建版本号,同时保存当前事务版本号到原来删除的行,
通过MVCC,虽然每行记录都需要额外的存储空间,更多的行检查工作以及一些额外的维护工作,但可以减少锁的使用,大多数读操作都不用加锁,读数据操作很简单,性能很好,并且也能保证只会读取到符合标准的行,也只锁住必要行。
来自 <https://blog.csdn.net/qq_35923749/article/details/82971131>