1. 引言

  行锁就是针对数据表中行记录的锁。这很好理解,比如事务 A 更新了一行,而这时候事务 B 也要更新同一行,则必须等事务 A 的操作完成后才能进行更新。

2. 从两阶段锁说起

  我先给你举个例子。在下面的操作序列中,事务 B 的 update 语句执行时会是什么现象呢?假设字段 id 是表 t 的主键。

  这个问题的结论取决于事务 A 在执行完两条 update 语句后,持有哪些锁,以及在什么时候释放。你可以验证一下:实际上事务 B 的 update 语句会被阻塞,直到事务 A 执行commit 之后,事务 B 才能继续执行。
  在 InnoDB 事务中,行锁是在需要的时候才加上的,但并不是不需要了就立刻释放,而是要等到事务结束时才释放。这个就是两阶段锁协议。
  知道了这个设定,对我们使用事务有什么帮助呢?那就是,如果你的事务中需要锁多个行,要把最可能造成锁冲突、最可能影响并发度的锁尽量往后放。
假设你负责实现一个电影票在线交易业务,顾客 A 要在影院 B 购买电影票。我们简化一点,这个业务需要涉及到以下操作:

  1. 从顾客 A 账户余额中扣除电影票价;
  2. 给影院 B 的账户余额增加这张电影票价;
  3. 记录一条交易日志。

3. 死锁和死锁检测

  当并发系统中不同线程出现循环资源依赖,涉及的线程都在等待别的线程释放资源时,就会导致这几个线程都进入无限等待的状态,称为死锁。这里我用数据库中的行锁举个例子。

  这时候,事务 A 在等待事务 B 释放 id=2 的行锁,而事务 B 在等待事务 A 释放 id=1 的行锁。事务 A 和事务 B 在互相等待对方的资源释放,就是进入了死锁状态。当出现死锁以后,有两种策略:

  1. 直接进入等待,直到超时。这个超时时间可以通过参数innodb_lock_wait_timeout 来设置。
  2. 发起死锁检测,发现死锁后,主动回滚死锁链条中的某一个事务,让其他事务得以继续执行。将参数 innodb_deadlock_detect 设置为 on,表示开启这个逻辑。

  正常情况下我们还是要采用第二种策略,即:主动死锁检测,而且innodb_deadlock_detect 的默认值本身就是 on。主动死锁检测在发生死锁的时候,是能够快速发现并进行处理的,但是它也是有额外负担的。

  怎么解决由这种热点行更新导致的性能问题呢?

  • 如果你能确保这个业务一定不会出现死锁,可以临时把死锁检测关掉。但是这种操作本身带有一定的风险,因为业务设计的时候一般不会把死锁当做一个严重错误,毕竟出现死锁了,就回滚,然后通过业务重试一般就没问题了,这是业务无损的。而关掉死锁检测意味着可能会出现大量的超时,这是业务有损的。
  • 另一个思路是控制并发度。根据上面的分析,你会发现如果并发能够控制住,比如同一行同时最多只有 10 个线程在更新,那么死锁检测的成本很低,就不会出现这个问题。一个直接的想法就是,在客户端做并发控制。但是,你会很快发现这个方法不太可行,因为客户端很多。我见过一个应用,有 600 个客户端,这样即使每个客户端控制到只有 5 个并发线程,汇总到数据库服务端以后,峰值并发数也可能要达到 3000。

07丨行锁功过:怎么减少行锁对性能的影响相关推荐

  1. java中的锁(悲观锁、乐观锁、可重入锁、不可重入锁、公平锁、非公平锁、自旋锁、阻塞锁...)

    Lock接口 1.简介.地位.作用 ① 锁是一种工具,用于控制对共享资源的访问 ② Lock和synchronized,这两个是最常见的锁,它们都可以达到线程安全的目的,但是在使用和功能上又有较大的不 ...

  2. 七、行锁功过:怎么减少行锁对性能的影响?

    文章目录 前言 1 从两阶段锁说起 2 死锁和死锁检测 前言 前面介绍了 MySQL 的全局锁和表级锁,接下来我们就来讲讲 MySQL 的行锁. MySQL 的行锁是在引擎层由各个引擎自己实现的.但并 ...

  3. mysql某个表被行锁了_MySQL中的锁(表锁、行锁)

    锁是计算机协调多个进程或纯线程并发访问某一资源的机制.在数据库中,除传统的计算资源(CPU.RAM.I/O)的争用以外,数据也是一种供许多用户共享的资源.如何保证数据并发访问的一致性.有效性是所在有数 ...

  4. mysql行级锁 表级锁 页级锁详细介绍_MySQL行级锁、表级锁、页级锁详细介绍

    页级:引擎 BDB. 表级:引擎 MyISAM , 理解为锁住整个表,可以同时读,写不行 行级:引擎 INNODB , 单独的一行记录加锁 表级,直接锁定整张表,在你锁定期间,其它进程无法对该表进行写 ...

  5. mysql 并发 锁表_MySQL中的锁(表锁、行锁) 并发控制锁

    https://github.com/MrLining/mysql/wiki/MySQL%E4%B8%AD%E7%9A%84%E9%94%81%EF%BC%88%E8%A1%A8%E9%94%81%E ...

  6. mysql 页级锁写法_MYSQL中表级锁、行级锁、页级锁介绍

    一.MYSQL数据库锁的种类 在数据库系统中,可以按照锁的粒度把数据库锁分为行级锁(INNODB引擎).表级锁(MYISAM引擎)和页级锁(BDB引擎 ). 1.行级锁 行级锁是Mysql中锁定粒度最 ...

  7. mysql表级锁和行级锁_Mysql的表级锁和行级锁

    表级锁 MySQL表级锁分为读锁和写锁. 读锁 用法:LOCK TABLE table_name [ AS alias_name ] READ 释放锁使用UNLOCK tables.可以为表使用别名, ...

  8. mysql锁机制——乐观锁、悲观锁;共享锁、排他锁、行表锁、间隔后码锁、MVCC 与 thinkphp的lock解析

    锁的引入 如果A有100元,同时对B.C转账,若处理是同时的,则此时同时读取A的余额为100元,在对两人转账后写回,A的余额不是0元而是50元.因此,为了防止这种现象的出现,要引入锁的概念,如只有在A ...

  9. 最全MySQL锁讲解:页锁、共享锁、行锁、表锁、悲观锁、乐观锁

    我们在操作数据库的时候,可能会由于并发问题而引起的数据的不一致性(数据冲突),如何保证数据并发访问的一致性.有效性,是所有数据库必须解决的一个问题,锁的冲突也是影响数据库并发访问性能的一个重要因素,从 ...

  10. MySQL锁机制详解-表锁与行锁

    文章目录 1. 数据库锁理论 2. 锁的分类 2.1 按数据操作的类型分类 2.2 按数据操作的颗粒度分类 3. 表锁的应用 3.1 表锁相关命令 3.2 给表加表共享读锁 3.3 给表加表独占写锁 ...

最新文章

  1. 校招经验分享—高考结束!校招还会远么~~
  2. python画图-python画图的两种方法
  3. 题目1148:Financial Management
  4. 专用DNS的CDN工作流程
  5. ROS学习--第3篇:ROS基础---创建工作空间和软件包
  6. 计算机java语言答案_【计算机二级Java语言】卷019
  7. 随机采样方法整理与讲解(MCMC、Gibbs Sampling等)
  8. php -q poller.php --force,cacti 安装后没有图像
  9. maven上传源码脚本
  10. Data-Mediator入门系列4----常用类说明
  11. Pycharm安装包(类库)的方法总结及解决包下载慢的问题
  12. Android 智能聊天机器人demo(类似小爱同学)
  13. 淘宝API 优惠券查询
  14. docker 内安装字体
  15. Pygame实战:下五子棋吗?信不信我让你几步你也赢不了?
  16. Linux 安装 Composer
  17. OpenCV分水岭分割算法2
  18. wetool企业微信营销管理系统开发
  19. 读遍装修书,我们帮你选出了最有用的10本
  20. 服务器远程登录用户在哪查看,RAKsmart VNC用户登录信息在哪查看?

热门文章

  1. Nodejs扩展,实现消息弹窗
  2. 35个Java代码性能优化总结
  3. spring+hibernate+struts整合(1)
  4. 86句管理名言:管理=勤奋+智慧+知识+心理学
  5. controller需要捕获异常吗_Spring之Controller异常处理
  6. php遍历文件夹下文件内容_php遍历文件夹下所有文件的代码示例
  7. 力士乐伺服电机编码器调零_力士乐伺服电机编码器故障维修来这里
  8. 大学计算机基础 课程的说课,大学计算机基础资料说课稿.ppt
  9. java小程序扑克牌_用Java来写一个模拟斗地主发牌的小程序
  10. Indesign CS6怎么添加框线_InDesign小小知识库