加入收藏 | 设为首页 | 会员中心 | 我要投稿 惠州站长网 (https://www.0752zz.com.cn/)- 办公协同、云通信、物联设备、操作系统、高性能计算!
当前位置: 首页 > 建站 > 正文

MySQL InnoDB锁介绍及不同SQL语句分别加什么样的锁

发布时间:2019-06-25 22:27:40 所属栏目:建站 来源:java互联网架构
导读:副标题#e# 阅读提示 本文所参考的MySQL文档版本是8.0,做实验的MySQL版本是8.0.13 本文主要参考了MySQL官方文档 InnoDB锁定和事务机制 本文还参考了何登成的 MySQL加锁处理分析、一个最不可思议的MySQL死锁分析 以及阿里云RDS-数据库内核组的 常用SQL语句的

前面我们说过“加什么样的锁”与以下因素相关

  1. 当前事务的隔离级别
  2. SQL是一致性非锁定读(consistent nonlocking read)还是DML或锁定读(locking read)
  3. SQL执行时是否使用了索引,所使用索引的类型(主键索引,辅助索引、唯一索引)

我们来看一下,不同的隔离级别下,使用不同的索引时,分别加什么锁。在讨论之前,我们先剔除无需讨论的情况

首先,普通SELECT 使用一致性非锁定读,因此根本不存在锁。无需讨论;

再者,作为开发者,我们几乎从来不会使用到隔离级别RU和Serializable。这两个隔离级别无需讨论。

于是,剩下的就是 给定锁定读SELECT或DML(INSERT/UPDATE/DELETE)语句,在不同隔离级别下,使用不同类型的索引时,分别会加什么样的锁?直接给出答案,其加锁原则如下

(一)、RR时,如果使用非唯一索引进行搜索或扫描,则在所扫描的每一个索引记录上都设置next-key lock。

这里“所扫描的每一个索引记录”是指当扫描执行计划中所使用的索引时,搜索遇到的每一条记录。WHERE条件是否排除掉某个数据行并没有关系,InnoDB并不记得确切的WHERE条件,InnoDB倔强的只认其扫描的索引范围(index range) 。

你可能觉得InnoDB在设置锁时蛮不讲理,竟然不管WHERE条件排除掉的某些行,这不是大大增加了锁的范围了嘛。不过,等我们了解了MySQL执行SQL时的流程,这就好理解了。MySQL的执行计划只会选择一个索引,使用一个索引来进行扫描,MySQL执行SQL语句的流程是,先由InnoDB引擎执行索引扫描,然后,把结果返回给MySQL服务器,MySQL服务器会再对该索引条件之外的其他查询条件进行求值,从而得到最终结果集,而加锁时只考虑InnoDB扫描的索引,由MySQL服务器求值的其他WHERE条件并不考虑。当然,MySQL使用index_merge优化时会同时使用多个索引的,不过,这个时候设置锁时也并不特殊,同样,对于所用到的每一个索引,InnoDB在所扫描的每一个索引记录上都设置next-key lock。

加的锁一般是next-key lock,这种锁住了索引记录本身,还锁住了每一条索引记录前面的间隙,从而阻止其他事务 向 索引记录前面紧接着的间隙中插入记录。

(编辑:惠州站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

推荐文章
    热点阅读