Mysql基于InnoDB的隔离级别
一、隔离级别的作用
当对同一行数据出现事务并发的时候,就需要用隔离级别去控制影响。隔离级别就是为了解决这块事务并发带来的数据一致性问题。
常见的问题:
1.脏读:一个事务读取到另一个事务还没有提交的事务内容。
举例:A事务将数据C从0改成1,但是事务还没有提交,这时候事务B读取数据C,理应读取到0,但是却读取到了1
理解:读到其他事务未提交的数据
2.不可重复读:一个事务两次重复读取同一条记录,由于这时候另一个事务更改了这条数据,导致第一个事务两次读取的数据不同。
例如:A事务读取数据C原始数据为0,这时候事务B修改数据C改成了1,并提交了事务,之后事务A再次读取C,发现C变成了1,同一个事务A前后两次读取数据C的内容却不一样
理解:读到其他事务已提交的数据
3.幻读:一个事务按照条件查询数据,没有对应的数据行,但是在插入数据时,又发现这行数据已经存在了。
例如:A事务读取数据C,发现没有,准备插入,这时候B事务插入了一条数据,此时A事务再去读的时候,发现还是没有。
理解:读不到其他事务已经提交的数据
这三个问题中脏读问题是最严重的,
二、四种隔离级别的介绍
1.读未提交(Read uncommitted)
2.读已提交(Read committed)
3.可重复读(Repeatable read)
4.串行化(Serializable )
三、隔离级别的实现
事务的隔离性是通过:readview+ MVCC + undoLog + 锁 四种技术共同实现的。
Mysql的Innodb引擎
四、企业中如何选择mysql的隔离级别
mysql的默认数据库隔离级别是 Repeatable Read(可重复读)俗称RR,但是一般我们在使用的时候都会将数据库的隔离级别设置成 Read committed(读已提交)俗称RC 这种隔离级别,但是这是为什么呢?
如果使用RR隔离级别,出现的问题:
1.在RR隔离级别下,条件列未命中索引会锁表!而在RC隔离级别下,只锁行!
2.在RR隔离级别下,存在间隙锁,导致出现死锁的几率比RC大的多!
3.在RR隔离级别下,使用statement模式的binlog做主从同步会出现数据不一致现象!
这块网上有两篇文章说的很详细(强烈建议):
为什么MySQL选择Repeatable Read作为默认隔离级别?
项目开发中MySQL应该选择什么事务隔离级别?
补充:
Mysql的主从同步,其实是用binLog来做的,binLog是有三种模式的:
1.statement模式:记录sql,例如:update stu a=1 where id = 1;这种
2.row模式:记录某一行数据
3.mix:混合模式