文章目录

  • 一、InnoDB表级锁
  • 二、意向共享锁和意向排他锁(针对整表)
  • 三、死锁
    • 1. 数据库中的死锁
    • 2. 死锁场景以及解决办法
    • 3. 操作
  • 四、锁的优化建议

一、InnoDB表级锁

我们知道,InnoDB是支持行锁,但不是每次都获取行锁,如果不使用索引的,那还是获取的表锁。而且有的时候,我们希望直接去使用表锁

在绝大部分情况下都应该使用行锁,因为事务的并发效率比表锁更高,但个别情况下也使用表级锁:

  • 事务需要更新大部分或全部数据,表又比较大,如果使用默认的行锁,给大部分行都加锁(此时不如直接加表锁),不仅这个事务执行效率低,而且可能造成其他事务长时间等待和锁冲突
  • 事务涉及多个表,比较复杂,如果都用行锁,很可能引起死锁,造成大量事务回滚

当我们希望获取表锁时,可以使用以下命令:

LOCK TABLE user READ  -- 获取这张表的读锁
LOCK TABLE user WRITE -- 获取这张表的写锁事务执行...COMMIT/ROLLBACK;      -- 事务提交或者回滚
UNLOCK TABLES;        -- 本身自带提交事务,释放线程占用的所有表锁

在使用表锁的时候,涉及到效率的问题:如果我们要获取一张表的排它锁X,最起码得确定,这张表没有被其他事务获取过S锁或X锁,以及这张表没有任何行被其他事务获取过行S或X锁

假如这张表有1000万个数据,那我怎么知道这1000万行哪些有行锁哪些没有行锁呢?

除了挨个检查,没有更好的办法,这就导致效率低下的问题

我们这里学习的意向共享锁和意向排他锁就是用来解决,由于需要加表锁而去挨个遍历数据,确定是否有某些数据被加了行锁,而导致的效率低下问题

二、意向共享锁和意向排他锁(针对整表)

意向锁的作用:为了可以更快速的获取表锁

意向共享锁(IS锁):事务在给一行记录加共享锁前,必须先取得该表的IS锁
意向排他锁(IX锁):事务在给一行记录加排他锁前,必须先取得该表的IX锁


(上面表格所有的锁都是针对整表)

  1. 在加行锁之前,由InnoDB存储引擎自动加上表的IS或IX锁,我们无法手动获取IS或IX锁
  2. 意向锁之间都兼容,不会产生冲突
  3. 意向锁存在的意义是为了更高效的获取表锁(表格中的X、S、IX、IS指的是表锁,不是行锁)
  4. 意向锁是表级锁,协调表锁和行锁的共存关系,主要目的是显示事务正在锁定某行或者试图锁定某行。

分析事务1获取行X锁和事务2获取表S锁

首先事务1需要给表的第10行数据加X锁,于是InnoDB存储引擎自动给整张表加上了IX锁。当事务2再想获取整张表的S锁时,看到这张表已经有别的事务获取了IX锁了,就说明这张表肯定有某些数据被加上了X锁,这就导致事务2不能给整张表加S锁了。此时事务2只能等待,无法成功获取表S锁

当某个事务要获取表的X锁时,不需要再检查哪些行被加上了X或S锁,只需要检查整表是否被加上IX或IS锁即可

三、死锁

1. 数据库中的死锁

MyISAM 表锁是 deadlock free 的, 这是因为 MyISAM 不支持事务,只支持表锁,而且总是一次获得所需的全部锁,要么全部满足,要么等待,因此不会出现死锁。如果是处理多张表,还是可能出现死锁问题的


在 InnoDB 中,除单个 SQL 组成的事务外,锁是逐步获得的,即锁的粒度比较小(行锁),这就决定了在 InnoDB 中发生死锁是可能的

死锁问题一般都是我们自己的应用造成的,和多线程编程的死锁情况相似,大部分都是由于我们多个线程在获取多个锁资源的时候,获取的顺序不同而导致的死锁问题。因此我们应用在对数据库的多个表做更新的时候,不同的代码段,应对这些表按相同的顺序进行更新操作,以防止锁冲突导致死锁问题

2. 死锁场景以及解决办法

死锁出现的场景如下:

事务1成功获取行锁1
事务2成功获取行锁2

事务1无法获取行锁2,被阻塞的同时也无法释放行锁1
事务2无法获取行锁1,被阻塞的同时也无法释放行锁2

此时所有的事务都阻塞住了,相当于进程内的所有线程都阻塞住了,发生了死锁问题

解决死锁办法:多个事务/线程获取多个相同资源锁的时候应该按照同样的顺序获取锁。与此同时,由于mysqld(MySQL Server守护进程)设置了事务阻塞的超时时间,事务不会阻塞很长时间,超时后事务处理失败,自动释放当前占有的锁

3. 操作

设置自动提交 以及 可重复读隔离级别,开启事务

查询一下表数据,在可重复读隔离级别使用的是MVCC提供的快照读,并没有加锁

事务1获取id=7的排他锁,事务2获取id=8的排他锁

事务1再次获取id=8的排他锁,发生阻塞

事务2再次获取id=7的排他锁

此时由于MySQL Server检测到发生了死锁,于是解除事务1的阻塞,进行事务1的rollback,释放其占有的行锁,于是事务2成功获取id=7的排他锁

四、锁的优化建议

  • 在能正确完成业务的前提下,为确保效率,尽量使用较低的隔离级别(必须避免脏读)

  • 设计合理的索引并尽量使用索引访问数据,使加锁更准确,减少锁冲突的机会,提高并发能力

  • 选择合理的事务大小,小事务发生锁冲突的概率小(事务越大,包含的SQL越多,可能包含更多的表资源和行资源的锁,增大了锁冲突的概率)

  • 不同的程序访问一组表时,应尽量约定以相同的顺序访问各表,对一个表而言,尽可能以固定的顺序存取表中的行。这样可以大大减少死锁的机会

  • 尽量用相等条件访问数据,这样可以避免间隙锁对并发插入的影响(其实等值查询也会加间隙锁)

  • 不要申请超过实际需要的锁级别

  • 除非必须,查询时不要显示加锁(在已提交读和可重复读隔离级别,MVCC提供了读取机制,不需要手动加锁)

MySQL 意向共享锁、意向排他锁、死锁相关推荐

  1. Mysql的共享锁和排他锁(转载)

    mysql锁机制分为表级锁和行级锁,本文就和大家分享一下我对mysql中行级锁中的共享锁与排他锁进行分享交流. 共享锁又称为读锁,简称S锁,顾名思义,共享锁就是多个事务对于同一数据可以共享一把锁,都能 ...

  2. MySQL的共享锁、排他锁、意向锁

    目录 一.共享锁(Shared Lock) 二.排他锁(EXclusive Lock) 三.意向锁(Intention Lock) MySQL锁的模式有三种:共享锁.排他锁.意向锁(意向共享锁.意向排 ...

  3. mysql innodb 排他锁_MySQL 针对 InnoDB 引擎锁的种类:行锁(共享锁和排他锁)和表锁(意向共享锁和意向排他锁)...

    InnoDB 锁快速到底 行锁:共享锁(S).排他锁(X) 表锁:意向共享锁(IS).意向排他锁(IX) 下面主要针对 MySQL 中行级锁中的共享锁(S)与排他锁(X)进行分析 共享锁又称为读锁,简 ...

  4. Mysql共享锁实例_mysql共享锁与排他锁用法实例分析

    本文实例讲述了mysql共享锁与排他锁用法.分享给大家供大家参考,具体如下: mysql锁机制分为表级锁和行级锁,本文就和大家分享一下我对mysql中行级锁中的共享锁与排他锁进行分享交流. 共享锁又称 ...

  5. mysql共享锁与排他锁

    mysql锁机制分为表级锁和行级锁,本文就和大家分享一下我对mysql中行级锁中的共享锁与排他锁进行分享交流. 共享锁又称为读锁,简称S锁,顾名思义,共享锁就是多个事务对于同一数据可以共享一把锁,都能 ...

  6. mysql排他锁_mysql共享锁与排他锁

    mysql锁机制分为表级锁和行级锁,本文就和大家分享一下我对mysql中行级锁中的共享锁与排他锁进行分享交流. 共享锁又称为读锁,简称S锁,顾名思义,共享锁就是多个事务对于同一数据可以共享一把锁,都能 ...

  7. mysql共享锁使用方法_浅谈Mysql共享锁、排他锁、悲观锁、乐观锁及其使用场景...

    Mysql共享锁.排他锁.悲观锁.乐观锁及其使用场景 一.相关名词 |--表级锁(锁定整个表) |--页级锁(锁定一页) |--行级锁(锁定一行) |--共享锁(S锁,MyISAM 叫做读锁) |-- ...

  8. mysql锁的应用场景_浅谈Mysql共享锁、排他锁、悲观锁、乐观锁及其使用场景

    Mysql共享锁.排他锁.悲观锁.乐观锁及其使用场景 一.相关名词 |--表级锁(锁定整个表) |--页级锁(锁定一页) |--行级锁(锁定一行) |--共享锁(S锁,MyISAM 叫做读锁) |-- ...

  9. 一文搞懂 mysql 中的共享锁、排他锁、悲观锁、乐观锁及使用场景

    目录 一.常见锁类型 二.Mysql引擎介绍 三.常用引擎间的区别 四.共享锁与排他锁 五.排他锁的实际应用 六.共享锁的实际应用 七.死锁的发生 八.另一种发生死锁的情景 九.死锁的解决方式 十.意 ...

  10. 浅谈Mysql共享锁、排他锁、悲观锁、乐观锁及其使用场景

    Mysql共享锁.排他锁.悲观锁.乐观锁及其使用场景 一.相关名词 |--表级锁(锁定整个表) |--页级锁(锁定一页) |--行级锁(锁定一行) |--共享锁(S锁,MyISAM 叫做读锁) |-- ...

最新文章

  1. Java深入了解String对象
  2. 包装类 || 装箱与拆箱
  3. 天翼云从业认证(4.2)网站建设实战
  4. linux之地址空间
  5. 没事研究下C#虚拟光驱,有所收获!
  6. 算法题-字符串匹配算法
  7. Reading query string values in JavaScript
  8. html给字体设置大小,如何设置html字体大小
  9. Invalid MEX-file '/xxx/lk.mexa64': /xxx/anaconda3/lib/./libharfbuzz.so.0: undefined symbol: FT_Done_
  10. 【考题·习题详解】数论知识+数学推导
  11. TensorFlow2.0 学习笔记(五):循环神经网络(RNN)
  12. MySQL数据库基础详解
  13. 抖音60秒视频权限开通方法
  14. sqlserver 抓取所有执行语句 SQL语句分析 死锁 抓取
  15. Mysql中语言分类和区别
  16. iphone下拉菜单卡住了_苹果手机怎么下拉菜单 苹果x右上角下拉失灵怎么办
  17. Matlab读Zygo干涉仪面形数据并进行37阶Zernike拟合(附Matlab代码)
  18. 诈骗罪可以提起刑事附带民事诉讼赔偿吗
  19. java开源项目源代码_java开源项目源代码
  20. BZOJ2178: 圆的面积并(格林公式)

热门文章

  1. iPhone、iPad 应用中潜藏的功能强大的 SFTP 工具(nplayer plus)
  2. Harris算子介绍
  3. 「2013-3-24」ClipSync, Youdao Note, GNote
  4. Powerbuilder遍历treeview
  5. APP兼容性测试需要注意哪几点?-alltesting云测试
  6. u8安装iis信息服务器,安装用友u8系统环境检查出iis服务器不符合怎么办?
  7. Dead reckoning的改进模型。
  8. python如何自动生成流程图
  9. 华为云分布式全系列产品组合,帮助企业轻松上云
  10. python 快速排序详解