• 《Mysql


    一:什么是锁?

      - 锁是计算机协调多个进程或纯线程并发访问某一资源的机制。

      - 通俗的来说,锁是一种对资源的保护形式

    二:锁分类
      - 表级锁

        - 开销小,加锁快,没有死锁,锁定粒度大,发生锁冲突的概率最大,并发度最低

      - 行级锁
        - 提到了行锁,也就提到了并发控制。Innodb

        - 开销大,加锁慢,有死锁,锁定粒度小,发生锁冲突的概率最小,并发度最高

      - 页面锁
        - 介于表/锁之间。

    三:如何加表锁?

      - 读锁
        - lock table 表名 read;

        - 对于读锁来说,不会堵塞读操作,但会堵塞写

        -  

       

      -  写锁

        -  lock table 表名 write;

        -  对于写锁来说,会堵塞同表的读/写操作,在写操作时,他们是串行的

        - 

      

      -  释放线程占用锁

        -  unlock tables; 

      

      - 注意

        -  使用 lock 语句执行的锁,不能 rollback回滚。

    四:MyIsam 表锁相关

      - 谁来加锁

        - 在执行 SELECT 时, 会自动给表加上读锁

        - 在执行 UPDATE/DELETE/…..,则会自动上写锁

      

      - 为什么表锁不会有死锁

        - MyIsam 在加锁时候,会一次获取涉及表所有的锁

        - 如若是读锁,就不能写,如果是写,就不能读,这也就是MyIsam为什么不会有死锁的原因

      

      - 锁调度

        - 当一个进程处理写/一个进程处理读时,不分先后,总是写先得到锁,读等待

        - 因为 MyIsam 认为写操作是比读更重要的,这也就是MyIsam 不适合大量更新插入操作的原因

        - 同时,一些特别长时间的 读,也会使得 写 进程被 ‘饿死’ 

    五:行锁加锁方式

      - 共享锁(S)

        - ......  lock in share mode;

        -  允许一个数据读取一行阻止其他事务获得相同数据的排他锁

        -  当加共享锁之后要执行修改时,会自动的给该行数据加入排它锁

        - 

      - 排他锁(X)

        - ......  for update;

        -  允许获得排它锁的更新数据,阻止其他数据获得相同数据的共享锁和排它锁

        -  等于写锁,阻止其他事务读取和更新,等待锁的释放

        - 

      -  意向共享锁(IS)

        -  Innodb 自动加锁

        -  对于SELECT则不会加锁

      -  意向排它锁(IX)

        - Innodb 自动加锁

        - 对于(UPDATE/INSERT/DELETE) 会自动加上 排它锁(X)

      - 乐观锁

        - 乐观锁是一种思想,它其实并不是一种真正的『锁』

        - 乐观锁认为,在整个数据库执行过程中,是不会产生冲突的。

        - 它会先尝试对资源进行修改,在写回时判断资源是否进行了改变,如果没有发生改变就会写回,否则就会进行重试,在整个的执行过程中其实都没有对数据库进行加锁;

      

      - 悲观锁

        - 悲观锁认为,这个操作是有冲突的,必须在获得锁的情况下才能执行操作。

        - 悲观锁就是一种真正的锁了,它会在获取资源前对资源进行加锁,确保同一时刻只有有限的线程能够访问该资源。

        - 其他想要尝试获取资源的操作都会进入等待状态,直到该线程完成了对资源的操作并且释放了锁后,其他线程才能重新操作资源;

    六:行锁实现方式

      -   Innodb 的行锁是根据索引来说实现的,也就是,是对索引的加锁

        -  也就是说,如果在不使用索引检索条件时,那么Innodb会对所有记录加锁,效果和表锁一样!

      -  对于使用范围查询的 < > 等,Innodb 也会在范围内(间隙)进行加锁,也就是所谓的 Next-Key 锁

    七:产生死锁的原因

      - 原因

        - 当两个或两个以上的事务相互持有和请求锁的时候,如果形成一个循环的依赖关系,就会产生死锁。

        - 简单来说,就是两个开启的事务在相互等待对方释放出自己需要的锁,结果形成了一个依赖的关系,产生死锁。

        - 示例

        - 

    八:减少锁冲突与死锁

      - 选用较低的隔离级别

      - 精心设计索引,尽量使用索引访问数据。使加锁更精确,避免锁冲突。

      - 选择合理的事务大小,小事务发生冲突的概率更小。

      - 显式加锁时,请一次请求足够级别的锁

      - 在访问不同表时,请尽量按照一定顺序访问表。对一个表来说,按照顺序访问,会大大减少死锁概率。

      - 尽量使用 = 来查询数据,避免间隙锁对并发插入的影响。

      - 除非必须,否则查询时不要加锁

      - 对一些特定的事务,加表锁有更好的效果。

    九:锁相关

      - 当开启一个 start transaction; 也等于隐形执行了一次 unlock tables;  

      -  在执行事务时,最好使用同一种存储引擎,因为 ROLLBACK/COMMIT 只能对同种引擎表做处理,如果不同,还需要对非事务表做特殊的处理.

      -  正常情况下,只有提交事务日志被记录到二进制文件中,但是由于存在非事务表,所以,回滚语句也会记录到二进制日志

  • 相关阅读:
    20.logging模块
    21.django中间件源码阅读
    18.configparser模块
    15.DRF学习以及相关源码阅读
    19.tcp_upd
    13.关于继承封装,以及反射
    16.html转pdf的一个小示例
    14.django返回展示一张图片
    GridView列标题修改
    ~为服务器端根目录符
  • 原文地址:https://www.cnblogs.com/25-lH/p/10698317.html
Copyright © 2020-2023  润新知