Mysql InnoDB事务隔离级别

隔离级别脏读(Dirty Read)不可重复读(NonRepeatable Read)幻读(Phantom Read)
未提交读(Read uncommitted)可能可能可能
已提交读(Read committed)不可能可能可能
可重复读(Repeatable read)不可能不可能可能
可串行化(Serializable )不可能不可能不可能
  • 未提交读(Read Uncommitted):允许脏读,也就是可能读取到其他会话中未提交事务修改的数据
  • 提交读(Read Committed):只能读取到已经提交的数据。Oracle等多数数据库默认都是该级别 (不重复读)
  • 可重复读(Repeated Read):可重复读。在同一个事务内的查询都是事务开始时刻一致的,InnoDB默认级别。在SQL标准中,该隔离级别消除了不可重复读,但是还存在幻读
  • 串行读(Serializable):完全串行化的读,每次读都需要获得表级共享锁,读写相互都会阻塞

具体来说:

未提交读:

在这个事物隔离级别下,只加写锁不加读锁,所以读的时候能读到其他事务加了写锁的数据,因为不会发生锁冲突。

所以当前事务还未提交的sql,其他的查询都能查到。比如:事务A中的有条sql为将id=1的数据从1修改为2,当事务还没提交时,其他的查询就能查到此时id=1的数据为2,但是事务A因为某些问题回滚了,此时这个查询到的2就是脏数据了。所以未提交读对于脏读、不可重复读、幻读都不能避免。

 

已提交读:

已提交读的事物隔离级别中会对数据的写入、修改、删除加行锁,读依然不加锁,但是是快照读,读取undo log中最新的记录,事务不提交不会生成记录,所以读不到其他事物未提交的修改。

所以可以避免其他查询事务还没提交的修改,也就是避免了脏读。

但还是不能避免不可重复读,比如当前事务A先读取了id=1的数据为1,读取完之后有条sql将数据修改为了2,此时事务A再来查询的时候就变成2了,与第一次查询到的1不同,两次查询结果不同,也就是不能重复的读取同一条数据。当然也避免不了幻读。

 

可重复读:

可重复读的事物隔离级别依然对数据的写入、修改、删除加行锁。但是在读操作中,如果是加了lock in share mode或者for update,是当前读,会加共享锁/拍他锁,保证了可重复读,如果不加,是快照读,依然读取的是undo log中的数据,并且读取小于当前事务id的最新一条已提交数据,此时数据版本已经确定了,后面的快照读取始终读取这个版本。保证可重复读。

具体的原因可以看:探究InnoDB可重复读 、 select加锁分析

所以可以避免不可重复读,因为在第一次读取的时候就对这条数据加了锁,其他的事务是不能对这条数据进行修改或者删除的,但是可以读。

但还是不能避免幻读,幻读说的是读取的数据条数不同,而不是值不同。比如事务A第一次count 学生分数=80的有10条,此时有一个事物B对表中插入了10条学生分数=80的记录,那么事务A再来查询的时候,学生分数=80的就有20条了,与第一次不一致,这就是幻读。

 

可串行化:

可串行化的事物隔离级别是读用读锁,写用写锁,读锁和写锁互斥。对读取数据加了表锁,整张表加了锁之后其他事物就无法对插入、删除和修改了,所以能避免幻读,但是并发太差,基本不会被使用。除非是在并发量小、对数据准确性要求高的情况下才会使用。

 

InnoDB默认的隔离级别是可重复读RR,用得最多的隔离级别是读已提交RC。

 

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值