导图社区 MYSQL 事务隔离级别
MYSQL事务隔离级别简单总结思维导图 参考: https://www.jianshu.com/p/f692d4f8a53e https://www.cnblogs.com/huanongying/p/7021555.html https://zhuanlan.zhihu.com/p/27035174
编辑于2020-09-20 17:14:04MYSQL 事务隔离级别
事务基本要素ACID
原子性Atomicity
事务开始后,所有操作要么全成功要么全失败,看作一个整体
一致性Consistency
事务开始前和结束后,数据库的完整性约束没有被破坏
比如A向B转账,不可能A扣了钱而B没收到
隔离性Isolation
不同事务是互相隔离,互不干扰的
不同事务在提交的时候,最终呈现的效果是串行的,一个事务的执行必然会阻塞其他事务的执行
持久性Durability
事务完成后,事务对数据库的所有更新都将被保存到数据库,不能回滚
隔离级别
未提交读 read uncommitted
最低等级
事务间完全不隔离
脏读、不可重复读、幻读
提交读 read commited
基于上一个级别,增加一个要求:事务读取的数据都是别的事务已经提交了的
不可重复读、幻读
只要在还没达到串行执行的情况下,总会有问题的,事务A select了一条数据,接着事务B update 这条数据,然后commit,这时候A还未提交,A再回来读这条数据,发现数据居然变了,按照我们之前所说,我们的目标是:对于一个事务本身来说,它所感知的数据库,应该只有它自己在操作,那么A会觉得自己并没有更新数据啊,怎么数据突然变了,这种情况叫做 不可重复读(Non-repeatable reads)
可重复读 repeatable read
幻读
在上一个级别的基础上,保证不会在一个事务内两次select同一条数据会出现变化,即是别的事务对你select的对象进行update操作不会影响。但是,如果是insert操作,在这个隔离级别还是会受到影响。事务A开启事务,并select一段有范围的数据,然后事务B开启事务,在先前A事务select的那段有范围的数据中insert一条数据,然后提交事务,接着事务A再select出来这段数据,发现数据多了一条,这种情况叫幻读(Phantom Read)
事务A select 范围数据,B进行insert,再select就多了数据
序列化读 serializable read
最高级别
每个事务都可以认为只有它自己在操作数据库
几种问题
脏读
脏读是指在一个事务处理过程里读取了另一个未提交的事务中的数据。 当一个事务正在多次修改某个数据,而在这个事务中这多次的修改都还未提交,这时一个并发的事务来访问该数据,就会造成两个事务得到的数据不一致。例如:用户A向用户B转账100元,对应SQL命令如下 update account set money=money+100 where name=’B’; (此时A通知B) update account set money=money - 100 where name=’A’; 当只执行第一条SQL时,A通知B查看账户,B发现确实钱已到账(此时即发生了脏读),而之后无论第二条SQL是否执行,只要该事务不提交,则所有操作都将回滚,那么当B以后再次查看账户时就会发现钱其实并没有转。
不可重复读
不可重复读是指在对于数据库中的某个数据,一个事务范围内多次查询却返回了不同的数据值,这是由于在查询间隔,被另一个事务修改并提交了。 例如事务T1在读取某一数据,而事务T2立马修改了这个数据并且提交事务给数据库,事务T1再次读取该数据就得到了不同的结果,发送了不可重复读。 不可重复读和脏读的区别是,脏读是某一事务读取了另一个事务未提交的脏数据,而不可重复读则是读取了前一事务提交的数据。 在某些情况下,不可重复读并不是问题,比如我们多次查询某个数据当然以最后查询得到的结果为主。但在另一些情况下就有可能发生问题,例如对于同一个数据A和B依次查询就可能不同,A和B就可能打起来了……
幻读
幻读是事务非独立执行时发生的一种现象。例如事务T1对一个表中所有的行的某个数据项做了从“1”修改为“2”的操作,这时事务T2又对这个表中插入了一行数据项,而这个数据项的数值还是为“1”并且提交给数据库。而操作事务T1的用户如果再查看刚刚修改的数据,会发现还有一行没有修改,其实这行是从事务T2中添加的,就好像产生幻觉一样,这就是发生了幻读。 幻读和不可重复读都是读取了另一条已经提交的事务(这点就脏读不同),所不同的是不可重复读查询的都是同一个数据项,而幻读针对的是一批数据整体(比如数据的个数)。
锁方式实现隔离性
基于锁的并发(Lock-Based Concurrency Control)
读写锁
两阶段提交锁 Two-phase locking
多版本并发控制 MVCC(Multi Version Concurrency Control)
MYSQL innodb 对于 MVCC 的实现
每一行数据保留两个系统版本号
更新版本号
删除版本号
版本号来源于事务id
事务ID是随时间推移而增长,而且不可重复的
select 操作
每次只会select具有比当前事务ID小的更新版本号的数据,而且删除版本号为空或者大于当前事务ID
update 操作
复制出一份副本,同事在更新版本号写入当前事务ID,并且把当前的事务ID写入之前的删除版本号中
insert 操作
写入新行,同时把当前事务ID写入更新版本号
delete 操作
在删除版本号中写入当前事务ID
优势
读不加锁,读写不冲突