Exploring
首页
  • Java

    • 面向对象的思想OOP
    • 浅谈Java反射原理
    • endorsed覆盖JDK中的类
  • 认证与授权

    • LDAP概念和原理介绍
    • OAuth2介绍
  • Impala

    • Impala 介绍
  • MySQL

    • 关于MySQL的一些面试题
    • 解决MySQL不到中文数据
    • 数据库之事务与实现原理
  • Oracle

    • oracle的表空间,用户管理,表操作,函数
    • oracle的查询、视图、索引
    • plsql简单入门
  • Redis

    • 数据类型详解
    • 跳越表
    • 数据持久化的两种方式
  • 共识算法

    • gossip
  • RPC

    • GRPC初识与快速入门
    • ProtocolBuffer基本语法
  • RabbitMQ

    • RabbitMQ入门程序之HelloWorld
    • RabbitMQ之工作模式
  • Zookeeper

    • Zookeeper一文入门
  • Docker

    • Docker入门初体验
  • Maven

    • 把自己的包到Maven中央仓库
    • Maven之自定义插件
  • Nginx

    • nginx的安装
    • nginx的配置文件
    • nignx 的变量
  • Tomcat

    • Servlet3通过SPI进行注册组件
  • Vagrant

    • vagrant 初始化
    • vagrant 常用配置
    • vagrant 自己制作 box
  • Linux

    • 启动方式 Systemd
    • 后台服务
    • 防火墙与 Iptables
  • 设计模式

    • 设计模式-代理
    • 设计模式-单例模式
    • 设计模式-迭代器
  • 分布式

    • CAP 理论
  • 数据结构

    • 数据结构之堆Heap
    • 数据结构之哈希表
    • 数据结构之队列
  • 计算机网络

    • HTTP与HTTPS详解
    • 浅谈DNS协议
    • ISP中的网络层
  • 算法

    • 常用查找算法及Java实现
    • 常用排序算法及Java实现
    • 迪杰斯特拉算法
  • 操作系统

    • 操作系统之进程调度算法
    • 操作系统之进程通讯IPC
    • 操作系统之内存管理
  • 抓包

    • 生成安卓系统证书
  • 加解密

    • 常见加密算法
    • 公开秘钥基础知识
    • RSA 解析
  • Windows

    • scoop 包管理
    • windows-terminal 配置
    • 增强 PowerShell
归档
Github (opens new window)
首页
  • Java

    • 面向对象的思想OOP
    • 浅谈Java反射原理
    • endorsed覆盖JDK中的类
  • 认证与授权

    • LDAP概念和原理介绍
    • OAuth2介绍
  • Impala

    • Impala 介绍
  • MySQL

    • 关于MySQL的一些面试题
    • 解决MySQL不到中文数据
    • 数据库之事务与实现原理
  • Oracle

    • oracle的表空间,用户管理,表操作,函数
    • oracle的查询、视图、索引
    • plsql简单入门
  • Redis

    • 数据类型详解
    • 跳越表
    • 数据持久化的两种方式
  • 共识算法

    • gossip
  • RPC

    • GRPC初识与快速入门
    • ProtocolBuffer基本语法
  • RabbitMQ

    • RabbitMQ入门程序之HelloWorld
    • RabbitMQ之工作模式
  • Zookeeper

    • Zookeeper一文入门
  • Docker

    • Docker入门初体验
  • Maven

    • 把自己的包到Maven中央仓库
    • Maven之自定义插件
  • Nginx

    • nginx的安装
    • nginx的配置文件
    • nignx 的变量
  • Tomcat

    • Servlet3通过SPI进行注册组件
  • Vagrant

    • vagrant 初始化
    • vagrant 常用配置
    • vagrant 自己制作 box
  • Linux

    • 启动方式 Systemd
    • 后台服务
    • 防火墙与 Iptables
  • 设计模式

    • 设计模式-代理
    • 设计模式-单例模式
    • 设计模式-迭代器
  • 分布式

    • CAP 理论
  • 数据结构

    • 数据结构之堆Heap
    • 数据结构之哈希表
    • 数据结构之队列
  • 计算机网络

    • HTTP与HTTPS详解
    • 浅谈DNS协议
    • ISP中的网络层
  • 算法

    • 常用查找算法及Java实现
    • 常用排序算法及Java实现
    • 迪杰斯特拉算法
  • 操作系统

    • 操作系统之进程调度算法
    • 操作系统之进程通讯IPC
    • 操作系统之内存管理
  • 抓包

    • 生成安卓系统证书
  • 加解密

    • 常见加密算法
    • 公开秘钥基础知识
    • RSA 解析
  • Windows

    • scoop 包管理
    • windows-terminal 配置
    • 增强 PowerShell
归档
Github (opens new window)
  • MySQL

    • 关于MySQL的一些面试题
    • 解决MySQL不到中文数据
    • 数据库之事务与实现原理
    • MyISAM和InnoDB引擎区别
    • MySQL不同隔离级别下的加锁情况
      • 简介
      • REPEATABLE READ
      • READ COMMITTED
      • READ UNCOMMITTED
      • SERIALIZABLE
      • 参考文档
    • MySql常用指令集
    • MySQL的索引
    • MySQL的字符集与校对规则
    • MySQL调优利器Explain
    • MySQL死锁的调试
    • MySQL之Gap-Locks与Next-key-Locks
    • SQL之组内排序
  • Oracle

  • Redis

  • 数据库
  • MySQL
unclezs
2020-10-14
0
目录

MySQL不同隔离级别下的加锁情况

# 简介

InnoDB的四个事务隔离级别:1992标准: READ UNCOMMITTED, READ COMMITTED, REPEATABLE READ,和 SERIALIZABLE。默认隔离级别InnoDB是 REPEATABLE READ。

那么在各个隔离级别的加锁情况也略有不同。

# REPEATABLE READ

这是的默认隔离级别 , 同一事务中的一致读取将读取第一次读取建立的快照。这意味着,如果您SELECT 在同一事务中发出多个普通(非锁定)语句,则这些 SELECT语句彼此之间也是一致的。

对于锁定读取 (SELECT使用FOR UPDATE或FOR SHARE), UPDATE和 DELETE语句,锁定取决于该语句使用的是具有唯一搜索条件的唯一索引还是范围类型搜索条件。

  • 对于具有等值查询的条件的唯一索引,InnoDB仅锁定找到的索引记录,而不锁定其前的间隙,也就行是只加行级锁不加间隙锁。
  • 对于其他查询条件(不管索引类型),使用间隙锁和next-key lock来进行锁定。

# READ COMMITTED

因为READ COMMITTED在执行锁定读取(SELECT 使用FOR UPDATE或FOR SHARE),UPDATE 语句和DELETE 语句的时候,InnoDB仅锁定索引记录,而不锁定它们之间的间隙。所以可以在这条锁定记录旁边插入数据,导致幻读。

加锁情况:

  • 对于UPDATE或 DELETE语句, InnoDB仅对其更新或删除的行加锁。MySQL评估WHERE条件后,将释放不匹配行的行级锁 。这大大降低了死锁的可能性,但是仍然可以发生。
  • 对于UPDATE语句,如果某行已被锁定,则InnoDB 执行 “semi-consistent” 读取,也就是说将事务A中修改后提交的最新数据反馈给MySQL,让事务B拿到事务A一句提交的最新数据进行比较where匹配情况。也就是读已经提交的数据进行比较。而RR隔离级别就是会直接阻塞等待,不会拿最新提交的数据比较。
    CREATE TABLE t (a INT NOT NULL, b INT) ENGINE = InnoDB;
    INSERT INTO t VALUES (1,2),(2,3),(3,2),(4,3),(5,2);
    COMMIT;
    
    # Session A
    START TRANSACTION;
    UPDATE t SET b = 5 WHERE b = 3;
    
    # Session B
    UPDATE t SET b = 4 WHERE b = 2;
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
  • 但是对于等值查询的唯一索引,即使有第二个update来之后,也不会进行semi-consistent读取,而是阻塞住,等待第一个update结束后才进行。
    CREATE TABLE t (a INT NOT NULL, b INT, c INT, INDEX (b)) ENGINE = InnoDB;
    INSERT INTO t VALUES (1,2,3),(2,2,4);
    COMMIT;
    
    # Session A
    START TRANSACTION;
    UPDATE t SET b = 3 WHERE b = 2 AND c = 3;
    
    # Session B
    UPDATE t SET b = 4 WHERE b = 2 AND c = 4;
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10

# READ UNCOMMITTED

SELECT语句以非锁定方式执行,但可能使用行的早期版本。因此,使用这个隔离级别,这样的读取是不一致的。这也叫脏读。否则,此隔离级别的工作方式与READ COMMITTED类似。

# SERIALIZABLE

这个级别类似于RR,但是InnoDB隐式地将所有纯SELECT语句转换为SELECT ... FOR SHARE 如果禁用自动提交,则为共享。如果启用了自动提交,则选择是它自己的事务。因此,已知它是只读的,如果作为一致(非锁定)读取执行,则可以序列化它,并且不需要阻塞其他事务。(若要强制普通选择阻止其他事务已修改选定行,请禁用自动提交。)

# 参考文档

Transaction Isolation Levels (opens new window)

Locks Set by Different SQL Statements in InnoDB (opens new window)

在 GitHub 编辑此页 (opens new window)
上次更新: 2024/02/25, 12:11:11
MyISAM和InnoDB引擎区别
MySql常用指令集

← MyISAM和InnoDB引擎区别 MySql常用指令集→

Theme by Vdoing | Copyright © 2018-2024 unclezs
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式