【MySQL】MySQL默认事务隔离级别 —— Repeatable Read

阅读更多

MySQL 的默认事务隔离级别是 Repeatable Read(可重复读)。

Oracle 的默认事务隔离级别是 Read Committed(读已提交)。

这是一个比较“怪”的现象。毕竟这两个事务隔离级别是差异是比较大的,而这两个数据库都是通用型的产品。

真实原因是MySQL为了规避一个数据复制场景中的缺陷,而选择 Repeatable Read 作为默认隔离级别。

 

基于 Statement 的 binlog

binary log 的主要用途

MySQL的 binary log 记录了数据库的“事件”。这些“事件”描述了数据库的改动,包括 表的创建、数据修改等。

 

binary log 主要用于:

  • 主从复制。主库 master 会将其 binary log 中的数据改动记录(“事件”)发送给 从库 slave。从库执行这些“事件”使数据与主库保持一致。
  • 数据恢复

 

binary log 的三种模式

binary log 有三种模式:

  • Statement:记录的是可能改变数据的SQL语句
  • Row:记录的是每行数据的变更
  • 混合模式:
    默认使用 Statement 格式的记录;
    当遇到可能引起 “基于Statement的数据复制问题” 时自动转换为 Row 模式。

 

基于Statement的数据复制问题

【MySQL】MySQL默认事务隔离级别 —— Repeatable Read_第1张图片
 

上述两个事务的隔离级别都是 Read-Committed。

真实的执行顺序是 先删后插。而 binlog 中记录的 Statement 顺序为 先插后删

当基于这份 Statement 格式的 binlog 进行主从复制或恢复数据时,得到的最终数据与实际情况不符。

 

两种解决方法:

  • 选用 Row 模式 的 binlog
    针对实际数据行的记录当然可以准确反映改动历史
  • 选用 Repeatable-Read 事务隔离级别
    “可重复读”隔离级别下,delete、insert 等语句会对数据加 间隙锁。上述Session2中的insert语句将被阻塞,直到session1 commit;

因为早期MySQL只支持 Statement 格式的 binlog,所以只能采用 Repeatable-Read 隔离级别来规避数据不一致的风险。

从 5.7.7 开始,MySQL的默认 binlog 格式已经是 ROW

 

选哪种事务隔离级别?

大多数项目中可以选 Read-Committed(读已提交),既降低死锁几率,又能提升并发性能。同时选用 Row 模式的binlog。

 

当然,这类 “最终一致性”的事务解决方案可能无法满足某些特殊项目的需求,需要采用 Serializable (串行)的隔离级别。

 

  • 【MySQL】MySQL默认事务隔离级别 —— Repeatable Read_第2张图片
  • 大小: 17.9 KB
  • 查看图片附件

你可能感兴趣的:(mysql,oracle)