zoukankan      html  css  js  c++  java
  • 行锁的三种算法

    一、Record Lock:单个记录上的锁

       Record Lock总是会锁住索引记录,如果InnoDB存储引擎表在建立的时候没有设置任何一个索引,那么这时InnoDB存储引擎会使用隐式的主键来进行锁定。

    、Gap Lock:间隙锁

       设计目的:是为了解决Phantom Problem(幻象/幻读),利用这种锁技术,锁定的不是单个值,而是一个范围。

    三、Next-Key Lock:Gap Lock+Record Lock

       Next-Key Lock是结合了Gap Lock和Record Lock的一种锁定算法,在此种算法下,InnoDB对于行的查询都是采用这种锁定算法。

      例如:

        有10、11、13、20这四个值,那么索引可能被Next-Key Locking的区间为:

        1、(-∞,10]

        2、(10,11]

        3、(11,13]

        4、(13,20]

        5、(20,+∞)

      除了Next-Key Locking,还有Previous-Key Locking,如上面的例子,可锁定的区间为:

        1、(-∞,10)

        2、  [10,11)

        3、  [11,13)

        4、  [13,20)

        5、  [20,+∞)

      然而,当查询的索引含有唯一属性时,InnoDB存储引擎对Next-Key Lock进行优化,将其降级为Record Lock,即仅锁住索引本身,而不是范围。如表中有1,2,5的id数据:

      

      会话A首先对a=5进行X锁。而由于a是主键且唯一,因此锁定的仅是5这个值,而不是(2,5)的范围,这样在B中插入值4不会阻塞,可以立即插入并返回。即锁定由Next-Key Lock算法降级为Record Lock,从而提高了并发性。

       Next-Key Lock降级为Record Lock仅在查询的列唯一索引的情况下。

      若是辅助索引,则情况会完全不同如:

      CREATE TABLE z(a INT,b INT,PRIMARY KEY(a),KEY(b))

      INSERT INTO z SELECT 1,1;

      INSERT INTO z SELECT 3,1;

      INSERT INTO z SELECT 5,3;

      INSERT INTO z SELECT 7,6;

      INSERT INTO z SELECT 10,8;

      表z的b列是辅助索引,若在会话A中执行下面的SQL:

      SELECT * FROM z WHERE b=3 FOR UPDATE;

      这是Sql语句通过索引列b进行查询,因此其使用传统的Next-Key Locking加锁,并且由于两个索引,其需要分别进行锁定。对于聚集索引,其仅对a等于5的索引加上record Lock对于辅助索引,其加上的是Next-Key Lock,锁定的范围是(1,3),需要注意的是,InnoDB存储引擎还会对辅助索引下一个键值加上gap lock,即还有一个辅助索引的范围为(1,6)的锁,因此,在B会话中运行下面的Sql语句,都会被阻塞:

      SELECT * FORM z WHERE a=5 LOCK IN SHARE MODE;

      INSERT INTO z SELECT 4,2;

      INSERT INTO z SELECT 6,5;

      而执行下面的语句,不会阻塞:

      INSERT INTO z SELECT 8,6;

      INSERT INTO z SELECT 2,0;

      INSERT INTO z SELECT 6,7;

      在默认的事务隔离级别下,即REPEATABLE READ下,InnoDB存储引擎采用Next-Key Locking机制来避免Phantom Problem(幻象问题)

  • 相关阅读:
    IO模型
    协程
    线程
    进程
    网络编程
    模块二
    面向对象(二)
    面向对象(一)
    优化异常报错
    python 模块
  • 原文地址:https://www.cnblogs.com/hyunbar/p/11133107.html
Copyright © 2011-2022 走看看