MySQL 默认的事务隔离级别是什么?为什么选择这个级别?
MySQL 默认的事务隔离级别是什么?为什么选择这个级别?
回答重点
MySQL 默认的隔离级别是可重复读( Repeatable Read ),即 RR。
原因是为了兼容早期 binlog 的 statement 格式问题,如果是使用读已提交、读未提交等隔离级别,使用了 statement 格式的 binlog 会导致主从(备)数据库数据不一致问题。
扩展知识
进一步分析 binlog statement 格式和可重复级别的影响
接下来我们来展开讲解下,便于大家理解。
MySQL 在使用过程中,为了避免单台故障,需要使用主从(备)机制:

而 MySQL 的主从(备)涉及 binlog 的复制,即从(备)库的数据是通过 binlog 从主库复制过来的。

在早期,MySQL binlog 仅支持 statement 格式,这个格式其实存的就是原先的SQL 语句,这就使得在读未提交(ru)和读提交(rc)两种隔离级别下会出问题。
我们来实际看个例子:
例如有两个事务 A 和 B ,以下图的时间顺序执行:

在读已提交隔离级别且手动提交事务的情况下, 插入的 5 这条记录会被保留。
但是由于事务 B 先提交,所以它会先被记录在 binlog 中,这个操作就导致了问题。
binlog 的记录顺序是:

使得从库同步 binlog 重放的时候,先执行了 insert 再执行 delete,这就使得从库的数据与主库不一致了!, 5 这条记录也会被删除了。
所以,为了避免这个问题,只能默认为可重复读级别。因为这个隔离级别下有间隙锁(Gap Locks)、临键锁(Next-Key Locks),所以事务 B 是无法先提交的,会被事务 A 阻塞,因此 binlog 的记录只能是先 delete 再 insert ,这样就没问题了。
Comments