zoukankan      html  css  js  c++  java
  • 四、行锁(Mysql实战45讲笔记-基础)

    6. 行锁

     MySQL的行锁是引擎层各引擎自己实现的,不是所有引擎都支持行锁,MyISAM 就不支持。

    行锁针对的数据表中行记录的锁,比如事务a更新某一行,事务b也要更新同一行,那必须等事务a执行完。

    6.1 二阶段锁

    锁的添加与释放分到两个阶段进行,之间不允许交叉加锁和释放锁。 也就是在事务开始执行后为涉及到的行按照需要加锁,但执行完不会马上释放,而是在事务结束时再统一释放他们。

    下面的案例中,事务a中update两行数据,这个两行数据都被加锁,在事务a commit后,事务b才能执行。所以在事务中应当进行把会造成锁冲突、影响并发度的锁往后放。

    image-20210406153526256

    如下图,修改id=2的数据,会引起锁冲突,所以将修改id=2的数据放到最后,不影响事务中其他语句的执行,减少事务之间的锁等待,提升了并发度

    执行顺序是:

    1. 事务a 修改id =1和id=2 的数据
    2. 事务b 修改id=3 的数据
    3. 事务a提交
    4. 事务b 修改id=2的数据,事务b 提交

    6.2 死锁和死锁检测

    死锁,事务a 等待事务b 释放id=2的行锁,事务b 等待事务a 释放id=1的行锁

    6.3 出现死锁后的解决方法:

    • 直接进入等待,超时就放弃,事务回滚。innodb_lock_wait_timeout 来设置,InnoDB中默认值是50s,虽然可以修改等待时间,但是如果设置的过短,容易误伤正常的锁等待。
    • 发起死锁检测,发现死锁后,主动回滚死锁链条中某一个事务,让其他事务继续执行。将参数 innodb_deadlock_detect 设置为 on,表示开启这个逻辑,默认就是开启的,不过是有性能的消耗。

    6.4 死锁检测的原理:

    每当一个事务被锁,要查看该事务所依赖的所依赖的线程是有没被其他线程锁住,如此循环查看,判断是否出现死锁。

    每个新来的被锁的线程,都要判断会不会由于自己的加入导致了死锁,这是一个时间复杂度是O(n)的操作。

    假设有1000个并发线程,同时更新一行,死锁的检测就是100万量级的,非常消耗cpu资源。

    6.5 控制并发度决死锁检测消耗性能问题:

    不要关闭死锁检测,关闭死锁,就需要等待超时,影响业务

    通过控制并发度,比如同时最多只能有10个线程更新,那么死锁检测成本就比较低。

    • 客户端进行并发控制:若客户端很多,即使单个客户端并发线程控制了,所有的客户端的并发线程汇总到服务端,峰值还是很高。
    • 中间件实现:并发控制做在数据库服务端之前
    • 也可以直接修改mysql,在进入引擎前排队
    • 分段汇总,比如一个商城的总收入,用十行数据记录,总收入是这10条数据的总和,每次增加总额,任意加到10条数据中的某一条,锁冲突的概率是之前的十分之一,相当于子账户的概念
  • 相关阅读:
    jquery的ready和简写
    javasript之ajax学习笔记
    用 Drupal 创建更好的评分系统的具体步骤
    drupal的FIVESTAR投票模块说明
    drupal中时间自定义格式
    drupal首页不显示默认内容列表方法
    基于 Zen 创建一个 Drupal 7 的主题(模板) ,一份简单的Drupal模板教程
    jquery tooltip事件
    HTML5地区自转代码
    转:Jmeter常见问题 (转载) http://www.51testing.com/?uid-128005-action-viewspace-itemid-84094
  • 原文地址:https://www.cnblogs.com/zhaoyuan72/p/14653483.html
Copyright © 2011-2022 走看看