zoukankan      html  css  js  c++  java
  • MySQL Innodb 中的锁

    MySQL Innodb 中的锁

    锁是用来解决并发冲突的必要手段,MySQL 中的并发主要是指多个线程同时对同一个数据库进行操作,其中不同线程可能代表不同的事务,本质上也就是对共享资源的不同事务的同时访问。

    Innodb 支持行级锁和意向锁。行级锁就是对行记录进行加锁,行级锁也分为两种类型,一种是共享锁( S 锁),一种是排他锁( X 锁)。意向锁为表级别的锁,也就是将锁定的对象分为多个层次,意向锁意味着事务希望在更细粒度上进行加锁,一般来说,意向锁是从上往下(数据库->表->页->记录)进行加锁,其中任何一个部分导致等待,那么该操作都会需要等待粗粒度的锁的完成。

    读的锁定操作

    一致性非锁定读

    MySQL 的默认事务隔离级别是 Repeatable Read,在事务隔离为 Repeatable Read 和 Read Committed 级别下,默认的读取方式即为一致性非锁定读。一致性非锁定读即为在访问行记录时,不需要等待该行上的 X 锁释放。Innodb 的一致性非锁定读是以多版本控制实现的,在多版本控制中,会保存修改之前数据的快照,作为恢复使用。

    需要注意的是:在 Repeatable Read 和 Read Committed 的两种级别下的一致性非锁定读也是不同的,Repeatable Read 隔离级别下,总是读取事务开始时的行数据,而 Read Committed 模式下总是读取该行版本上的最新快照。

    一致性锁定读

    默认情况下,在 Repeatable Read 和 Read Committed 隔离界别下,SELECT 语句对一行的读取是使用一致性非锁定读的,用户可以通过指定 SELECT 语句使用一致性锁定读,例如:

    1. SELECT ... FOR UPDATE
    2. SELECT ... LOCK IN SHARE MODE

    这两种方法可以分别给行记录加上一个 X 锁和 S 锁。

    外键和锁

    对于一个外键的更新和插入,首先需要查询父表中的记录,即主动对父表加一个 S 锁,这里必须使用一致性锁定读。如果不这么做,当另外事务 A 对父表的行记录进行了删除操作,而事务 B 打算在子表中添加一行与父表具有外键关系的行,事务 B 会读到存在该外键,从而添加(从快照中读取),但是实际上当事务 A 提交后,父表中将不存在该主键,从而导致父子表中完整性被破坏。

    行锁的三种方法

    Record Lock:单个行记录上的锁。

    Gap Lock:间隙锁,不包含记录本身。

    Next-Key Lock:锁定一个范围同时也锁定记录本身。

    在查询的列是唯一索引时,Next-Key Lock 会降级为 Record Lock,以提高并发效率。

    在 Repeatable Read 和 Read Committed 情况下使用行锁的方法不同,在 Repeatable Read 下,使用 Next-Key Lock,而在 Read Committed 情况下,使用 Record Lock。

    死锁的发生

    死锁发生的概率:与 n(事务的数量)和 r(每个事务操作的数量)以及 R(事务操作的数据集合)有关,前两个是正相关,后两个是负相关。

    AB-BA 死锁

    在这种情况下,事务 A 和事务 B 互相等待对方的加锁资源,从而导致死锁。InnoDB 存储引擎会回滚 undo log 记录小的事务。

    死锁 2

    如果当前事务持有了待插入记录的下一个记录的 X 锁,但是在等待队列中存在一个 S 锁的请求,则可能会发生死锁,这个通过举例可以很容易理解。

    假设事务 A 首先获取了 a = 4 的行记录的 X 锁,此时事务 B 请求 a <= 4 的 S 锁(阻塞,因为 X 和 S 锁不兼容),此时事务 A 在插入了 a = 3 的行记录。此时会发生死锁,InnoDB 存储引擎会回滚 undo log 记录大的事务。

  • 相关阅读:
    XSLT的Replace函数
    Predicate<T> 委托
    《人生的智慧》第二章 人的自身
    Kmeans文本聚类:获取weka计算的聚类中心,完成文本聚类
    VCKbase转载:C++调用ADO
    Kmeans文本聚类系列之如何调用Preprocess类
    Kmeans文本聚类系列之全部代码
    近期计划
    Kmeans 聚类之建立文档向量模型(VSM)
    LibSVM文本分类之结果统计
  • 原文地址:https://www.cnblogs.com/bdsir/p/8868510.html
Copyright © 2011-2022 走看看