事物的特性
A 原子性
C一致性
I隔离性
D持久性
mysql的事物隔离级别有哪些
RU 读已提交
RC 读未提交
RR 可重复读
S 串行化
不同的事物隔离级别会有哪些问题
RU 脏读 (两个事物读取,一个事物读取到了另一个事物还没有提交的数据)
RC 不可重复读(多次读取,得到的数据不一样)
RR 幻读(插入或者删除引起的,多次读取,读到的数据量不一样)
S 都可以解决 但是慢
mysql是如何解决不可重复的问题的
通过mvcc来解决
什么是mvcc?
多版本(一行数据的版本链)并发(场景)控制(读到的结果)
说人话就是:
一条数据,我允许,多个事物对他进行修改,并且控制得到的结果
原理
他是通过undolog版本链+readview读试图来控制的
版本链介绍一下
undolog&&mysql针对每一行数据都会有两个隐藏字段,事物id和指针(指向上个版本的指针)
readview读试图介绍一下
四个核心参数
1.当前事物id
2.活跃事物id列表
3.最大事物id
4.最小事物id
根据readview就可以根据版本链判断当前事物哪些可以读哪些不能读
在活跃事物列表中的,那就证明这个事物还没有被提交,所以一定不读
不在活跃事物列表中的,那就证明该事物已经提交了,所以一定读
比最小的事物id还要小,那证明已经被提交了,一定读
比最大的事物id还要大,那证明没有被提交。一定不读
当前事物id,那一定是读的,自己改的自己肯定堵
画图展示
当前事物id是38,38在活跃事物列表中,证明没有被提交的事物,一定不读
最小事物id的作用
提高查询效率,时间复杂度是O1,要不然就在当前活跃列表中查询 时间复杂度是ON
读已提交和可重复度的区别是什么
逻辑是只要readview读试图已确定,那就可以感觉版本链判断哪些是可以读到的
所以两个隔离级别的区别就是readview生成的时机不一样
1.读已提交是在每一次查询的时候都会生成新的readview,因为每次读我都要拿到最新的数据
2.可重复读是只有在第一次查询的时候生成readview
幻读
表象就是,多次读取,得到的数据量不一致,就是我这边读取数据的时候,另一个人插入或者删除了某一条数据导致的
怎么解决幻读?
核心思想,那我读取的时候不让你插入就完了,从根本中解决幻读的问题
select for update
next-key-lock 行锁+间隙锁
这种和mvcc的区别就是
mvcc我读的时候,别的事物可以修改,但是你改完我不读
这种行锁+间隙锁的方式是我读的时候就根本不让你改,从根本解决
mysql解决幻读
快照读的时候通过mvcc解决了幻读
当前读并没有解决幻读(是通过行锁+间隙锁解决的)
但是他并没有完全解决幻读,这个我觉得倒是无所谓的,我觉得幻读不是一个问题,而是一种表象,别人新增或和删除的时候,我就是应该读到最新的数据呀,这个是没问题的,但是如果业务逻辑需要特定的改动,那就从代码层面去解决,而不是依赖数据库了