zoukankan      html  css  js  c++  java
  • 【innoDB】加锁案例分析

    分析一条语句的加锁行为,我们需要知道:

    • 当前隔离级别是什么?
    • 语句是快照读还是当前读?
    • 是不是走的索引?
    • 索引是不是主键?
    • 索引唯一吗?

    快照读默认不加锁,走mvcc,下面分析一下当前读的常见场景,sql语句是:update t1 set name='xx' where id=10;

    RR隔离级别级别:

    可重复读通常需要加间隙锁保证不出现幻读。

    • 情形1- id是主键索引

      这种情况下只会在id=10的主键索引上加X锁

    • 情形2-id是非主键唯一索引

      唯一索引id=10上先被加X锁;还要在该记录的主键索引上加X锁;

      如果不存在id=10的记录,则要在id索引上加间隙锁,锁住id=10其前一条记录到其后一条记录这整个区间。

    • 情形3- id是非唯一索引

      所有索引到的记录都加上X锁,并在其主键索引上也加上X锁,并且要在锁住所有间隙。

      image-20211212203545964
    • 情形4-id不是索引

      因为id不是索引,所以该语句需要进行全表扫描,这种情况下会对主键索引的所有记录和间隙都加锁。这种情况并发度就很低了,而且如果记录很多锁的开销还非常大。

      似乎进行扫描时只要对满足条件的加锁即可,但实际上innodb会先对所有的记录加锁,然后在mysql server层会进行过滤,对不满足条件的记录释放锁(但这违背了2PL原则)。

    RC隔离级别下:

    基本和RR一样,不过不考虑幻读问题,不需要加间隙锁。

    • id是主键,同RR
    • id是唯一索引,同RR,不需要加间隙锁
    • id是非唯一索引,同RR,不需要加间隙锁
    • id不是索引,同RR,不需要加间隙锁

    串行化隔离级别:

    在串行化下,上述的当前读语句加锁行为和RR级别一样。

    不同的是串行化级别下所有读都是当前读,不走快照读,因此原本的快照读语句会加读锁。MVCC并发控制降级为Lock-Based CC。

  • 相关阅读:
    以最少的循环把两个数组里面的相同结果输出来
    解决PL/SQL Developer连接数据库时出现 “ORA-12541:TNS:无监听程序”错误
    AOP中Advice执行两遍的原因
    Java注释@interface的用法
    Spring进阶教程之在ApplicationContext初始化完成后重定义Bean
    Java的注解机制——Spring自动装配的实现原理
    基数排序简单Java实现
    jQuery的选择器中的通配符
    SEO 网站页面SEO优化之页面title标题优化
    IntelliJ IDEA 中文乱码解决
  • 原文地址:https://www.cnblogs.com/cpcpp/p/15684239.html
Copyright © 2011-2022 走看看