文章目录

  • 一、事务隔离机制的选择
  • 二、表级锁&行级锁
  • 三、排它锁(Exclusive)和共享锁(Shared)
    • 1. 测试不同事务之间排它锁和共享锁的兼容性
    • 2. 测试行锁加在索引项上
  • 四、串行化隔离级别测试

事务隔离级别的实现原理:简单来说就是各种锁机制和MVCC多版本并发控制

我们学习知识的时候,需要了解知识点出现的原因,什么情况下能用到这个知识

我们说到事务,就得说到事务的ACID特性,为什么需要隔离性呢?因为事务要能够允许并发执行,并发执行为了同时保证数据的安全性,一致性和并发的效率,就需要设置事务的隔离级别

一、事务隔离机制的选择

  • 如果我们完全不管,使用未提交读的事务隔离机制,任由这些线程并发操作数据库,那就会出现脏读(读取了未commit的数据)、不可重复读(两次查询值不同)、幻读(两次查询数据量不同)等问题,数据的安全性最低,优点是并发效率非常高,一般不会使用

  • 如果我们串行化(靠锁实现),通过锁给所有的事务都排个序,虽然数据的安全性提高了,并发的效率就太低了,一般也不会使用

  • 所以我们一般用的是已提交读、可重复读这两个隔离级别,平衡了数据的安全性,一致性以及并发的效率 ,是由MVCC多版本并发控制实现的(MVCC是已提交读和可重复读的原理,锁是串行化的原理)

二、表级锁&行级锁

表级锁:对整张表加锁。开销小(因为不用去找表的某一行的记录进行加锁,要修改这张表,直接申请加这张表的锁),加锁快,不会出现死锁;锁粒度大,发生锁冲突的概率高,并发度低

行级锁:对某行记录加锁。开销大(需要找到表中相应的记录,有搜表搜索引的过程),加锁慢,会出现死锁;锁定粒度最小,发生锁冲突的概率最低,并发度高

InnoDB存储引擎支持事务处理,表支持行级锁定,并发能力更好

  1. InnoDB行锁是通过给索引上的索引项加锁来实现的,而不是给表的行记录加锁实现的,这就意味者只有通过索引条件检索数据,
    InnoDB才使用行级锁,否则InnoDB将使用表锁
  2. 由于InnoDB的行锁实现是针对索引字段添加的锁,不是针对行记录加的锁,因此虽然访问的是InnoDB引擎下表的不同行,但如果使用相同的索引字段作为过滤条件,依然会发生锁冲突,只能串行进行,不能并发进行
  3. 即使SQL中使用了索引,但是经过MySQL的优化器后,如果认为全表扫描比使用索引效率高,此时会放弃使用索引,因此也不会
    使用行锁,而是使用表锁
    ,比如对一些很小的表,MySQL就不会去使用索引

三、排它锁(Exclusive)和共享锁(Shared)

排它锁,又称为X锁,写锁
共享锁,又称为S锁,读锁

读读(SS)之间是可以兼容的,但是读写(SX)之间,写写(XX)之间是互斥的

对事务加X和S锁之间有以下的关系:

  • 一个事务对数据对象A加了 S 锁,可以对A进行读取操作但不能进行update操作,加锁期间其它事务能对A加S锁但不能加 X 锁
  • 一个事务对数据对象A加了 X 锁,就可以对A进行读取和更新,加锁期间其它事务不能对A加任何锁

显式加锁:select … lock in share mode强制获取共享锁,select … for update获取排它锁

1. 测试不同事务之间排它锁和共享锁的兼容性

我们先查看表的SQL以及内容

查看隔离级别:

首先开启一个事务,给id=7的数据加上排它锁

在用另一个客户端开启事务

我们用另一个事务的服务线程给id=7的数据加上排它锁,阻塞了


我们尝试给id=7的数据加上共享锁,还是阻塞了

再获取id=8的共享锁和排它锁


但是可以成功获取id=8的共享锁和排它锁

总结:不同事务之间对于数据的锁,只有SS锁可以共存,XX、SX、XS都不能共存

2. 测试行锁加在索引项上

其实行锁是加在索引树上的


事务1用表的无索引字段name作为过滤条件

事务2现在同样想获取这条记录的排它锁,可想而知地失败了;那现在事务2获取不同行chenwei的记录的排它锁,试试能不能成功


事务2获取不同行chenwei的记录的排它锁,同样失败了

InnoDB是支持行锁的,刚才以主键id为过滤条件时,事务1和事务2获取不同行的锁是可以成功的。然而现在我们发现获取name为chenwei的排它锁也获取不到了,这是为什么?我们解释一下:

InnoDB的行锁是通过给索引项加锁来实现的,而不是给表的行记录加锁实现的

而我们用name作为过滤条件没有用到索引,自然就不会使用行锁,而是使用表锁。这就意味着只有通过索引检索数据,InnoDB才使用行级锁,如果做整表扫描,InnoDB将使用表锁!!!

我们给name字段加上索引

添加索引,开启事务后,重新获取不同行的排它锁


我们发现,给name加上索引后,两个事务可以获取到不同行的排它锁(for update),再一次证明了InnoDB的行锁是加在索引项上的

因为现在name走的是索引, 通过zhangsan在辅助索引树上找到它所在行记录的id是7,然后到主键索引树上,获取对应行记录的排他锁(MySQL Server会根据情况,在主键索引树和辅助索引树上加锁)

四、串行化隔离级别测试

在SERIALIZABLE隔离级别下,所有的事务都自动使用排它锁或共享锁,不需要用户手动加锁(for in share mode/for update)

设置串行化隔离级别

两个事务可以同时获取共享锁(SS共存)

现在让事务2插入数据

此时由于insert需要加排它锁,但由于事务1已经对整张表添加了共享锁,事务2无法再对表成功加锁(SX不共存)

rollback一下


因为我们给name加上了索引,以上的select相当于给name为zhangsan的数据加上了行共享锁

事务2 update

事务2不能update,因为此时已经被事务1的共享锁锁住了id=7 name=zhangsan这条记录的索引项

事务2在辅助索引树上找zhangsan,找到对应的主键值,然后去主键索引树找到相应的记录,但是发现这行记录已经被共享锁锁住了,事务2可以获取共享锁,但是不能获取排他锁


我们用主键索引id试试能不能update

依然阻塞住了,虽然我们where后面的字段现在使用的id而不是name,但是name也是通过辅助索引树找到对应的主键,再到主键索引树上找相应的记录,而主键索引树上的记录加了锁(MySQL Server会根据情况,在主键索引树和辅助索引树上加锁)

我们update id=8的数据,成功了。因为我们select的时候,只是给id=7 name=zhangsan的数据加上了行锁,我们操作id=8的数据当然可以成功

有索引,则使用行锁;没有索引,则使用表锁。

表级锁还是行级锁说的是锁的粒度,共享锁和排他锁说的是锁的性质,不管是表锁还是行锁,都有共享锁和排他锁的区分

MySQL表锁、行锁、排它锁和共享锁相关推荐

  1. MySQL中的表锁行锁共享锁很难吗?看了本文就清楚了哦

      MySQL数据库中的锁还是非常重要的,本文重点给大家详细的来介绍下MySQL数据中的各种锁. 一.表锁和行锁 1.表锁 表锁的优势:开销小:加锁快:无死锁 表锁的劣势:锁粒度大,发生锁冲突的概率高 ...

  2. mysql 表级别的锁和行级别的_MySQL 表锁和行锁机制

    案例分析 目前,MySQL常用的存储引擎是InnoDB,相对于MyISAM而言.InnoDB更适合高并发场景,同时也支持事务处理.我们通过下面这个案例(坑),来了解行锁和表锁. 业务:因为订单重复导入 ...

  3. mysql 表锁 MDL锁 行锁

    mysql 按照粒度分可以分为 全局锁 表锁 行锁 全局锁 给整个锁加上锁 Flush tables with read lock 让数据处于只读的状态 一般用户 场景:做全库的逻辑备份. 表锁 顾名 ...

  4. mysql怎么加全局锁_MySQL锁机制/管理(并发锁,行锁,表锁,预加锁,全局锁等等)

    MySQL实验室 1.?MySQL 中并发和隔离控制机制 Meta-data元数据锁:在table cache缓存里实现的,为DDL(Data Definition Language)提供隔离操作.一 ...

  5. Mysql INNODB引擎行锁的3种算法 Record Lock Next-Key Lock Grap Lock

    Mysql INNODB引擎行锁的3种算法 InnoDB存储引擎有3种行锁的算法,其分别是: □ Record Lock:单个行记录上的锁 Record Lock总是会去锁住索引记录,如果InnoDB ...

  6. mysql mvcc和行锁_mysql在RR的隔离级别下,究竟是通过MVCC解决幻读的还是通过行锁的next key算法解决的?...

    首先,我们需要搞懂几个隔离级别的意思和每个隔离级别会出现的问题.隔离级别分为:读未提交,读提交,可重复读和可串行化. 读未提交是最低级别的隔离级别,表示当一个事务还没有提交时,他所做的变更就被别的事务 ...

  7. 小福利,采用excel函数制作大屏可视化,用sumifs函数快速统计汇总数据,锁行锁列以及锁列不锁行

    小福利,采用excel函数制作大屏可视化,用sumifs函数快速统计汇总数据,锁行锁列以及锁列不锁行 源数据如下图所示 第一步处理源数据的效果是下图 其中根据年份变化,求总订单量.总销量.总销售额,只 ...

  8. mysql进阶: mysql中的锁(全局锁/表锁/行锁/间隙锁/临键锁/共享锁/排他锁)

    锁在生活中处处可见,门锁,手机锁等等. 锁存在的意义是保护自己的东西不被别人偷走/修改. 在mysql中锁的意义也是一样,是为了保护自己的数据不被别人进行修改,从而导致出现脏读,幻读等问题.在学习锁的 ...

  9. mysql某个表被行锁了_MySQL 行锁和表锁的含义及区别详解

    一.前言 对于行锁和表锁的含义区别,在面试中应该是高频出现的,我们应该对MySQL中的锁有一个系统的认识,更详细的需要自行查阅资料,本篇为概括性的总结回答. MySQL常用引擎有MyISAM和Inno ...

  10. MySql中的行锁和表锁的理解

    mysql 的 InnoDB引擎支持行锁,与Oracle不同,mysql的行锁是通过索引加载的,即是行锁是加在索引响应的行上的,要是对应的SQL语句没有走索引,则会全表扫描. 表锁:不会出现死锁,发生 ...

最新文章

  1. 2021 互联网大厂新年礼盒大比拼!
  2. python真的那么强大嘛-python强大吗
  3. vue访问完整外部链接数据_【Excel小技巧】链接外部数据的五个方法
  4. raise event when save - COM_PR_CHBADI_RAISE_WF_EVENT
  5. MySQL索引使用详解
  6. 新垣结衣自拍照_如何阻止自拍照出现在iPhone的自拍照专辑中
  7. AlvinZH双掉坑里了
  8. 【C语言重点难点精讲】C语言中的重要符号
  9. MinIO Client完全指南 ​​​​​​​
  10. 七月文章导读【TCP/IP相关】:解密 TCP/IP;什么是公网ip?什么是内网ip?为什么ip地址通常以192.168开头?
  11. php提供的魔术常量
  12. mysql学习day01
  13. java hasnext_java hasNext()使用实例解析
  14. 内核线程、轻量级进程、用户线程三种线程概念解惑(线程≠轻量级进程)
  15. 夏普电视出现android不动了,夏普电视常见故障问题分析与处理,电视机故障判断检修...
  16. 电脑需要u盘启动的解决办法--蓝屏修复
  17. 构建数据指标预警系统
  18. 4.IPv4和IPv6地址长度
  19. java实现 蓝桥杯 算法训练 操作格子
  20. 一个软件项目经理的心得和经验

热门文章

  1. talkback-6.1.1支持安卓6,也就是SdkVer=23的方法
  2. php5.3 环境,php5.3环境简单配置
  3. 2019 美国大学生数学建模竞赛(MCM/ICM)赛后回忆
  4. Pycharm中python运行环境与终端中python运行环境不一致
  5. ifnull mysql date,MySQL的CAST和IFNULL函数的问题
  6. ssssssssssssss 是收拾收拾收拾收拾收
  7. 安装编译QtXlsxWriter-master
  8. Java简易人员管理系统
  9. 初识网络基础《网络七层模型详解》
  10. 灯火阑珊的伤感短篇日志分享:我的伤,你永远不懂