MySql有四种隔离级别
- Read Uncommitted(读取未提交内容)
- Read Committed(读取提交内容)
- Repeatable Read(可重读)
- Serializable(可串行化)
Read Uncommitted(读取未提交内容)
在该隔离级别,所有事务都可以看到其他未提交事务的执行结果。这也造成了脏读这种问题。
- 事务A读取数据
- 事务B更新数据,但未提交
- 事务A再读数据,发现数据发生变化
- 事务B回滚
- 事务A再读数据,数据回到初始化
脏读,读取未提交的数据
Read Committed(读取提交内容)
在该隔离级别,事务只能读取已提交的事务的执行结果。
该隔离级别解决了脏读,但是出现了不可重复读问题。即事务两次查询,但是结果不一致。是因为在此期间,别的事务更新了数据并提交,即不可重复读
像Orcal这种数据库都采用该隔离级别。
Repeatable Read(可重读)
为了解决不可重复读问题,现在提出Repeatable Read(可重读)。
- 事务A初始化读取数据
- 事务B更新数据并提交
- 事务A正常读取数据,数据并未改变
- 事务A提交本次事务,并再次提交,可读更新后的数据
该隔离级别易造成幻读,即读取数据并不是最新的数据
Serializable(可串行化)
即先来先用
- 事务A初始化使用数据
- 事务B想要使用同一份数据,必须等待事务A结束使用
- 事务A提交事务
- 事务B可使用该数据
serializable完全锁定字段,若一个事务来查询同一份数据就必须等待,直到前一个事务完成并解除锁定为止。是完整的隔离级别,会锁定对应的数据表格,因而会有效率的问题。
介绍完了四种隔离级别,来了解MYsql为什么要使用可重读RR作为默认隔离级别,Orcal为什么要用读已提交RC作为默认级别
binlog是记录所有数据库表结构变更(例如CREATE、ALTER TABLE…)以及表数据修改(INSERT、UPDATE、DELETE…)的二进制日志。
在mysql 5以前,binlog只有statement一种格式。现在有三种格式
- statement:记录的是修改SQL语句
- row:记录的是每行实际数据的变更
- mixed:statement和row模式的混合
为什么MySql默认使用RR隔离级别?
只有statement这种格式,在主从复制时候,会有大量的不一致这样的bug。所以mysql选择RR作为默认隔离级别。
为什么Orcal这些数据库用RC作为默认隔离级别?
- 在RR隔离级别下,存在间隙锁,导致出现死锁的几率比RC大的多!
- 在RR隔离级别下,条件列未命中索引会锁表!而在RC隔离级别下,只锁行
- 在RC隔离级别下,半一致性读(semi-consistent)特性增加了update操作的并发性!
在RC级用别下,主从复制用什么binlog格式?
row格式,是基于行的复制!