• mysql悲观锁是行锁还是表锁?


    mysql悲观锁是行锁还是表锁?

    结论

    悲观锁在非主键、非索引时是表锁,在主键、索引时是行锁。

    使用悲观锁

    在查询语句后面加上 for update 开启悲观锁。

    select * from table where col = xx for update;
    
    • 1

    悲观锁: 在事务执行开始加锁,此时其他事务无法读写,等待事务完成,其他事务才可以获得这个锁。

    验证悲观锁

    1. 关闭自动提交 set @@autocommit = 0; (设置事务是手动提交。 0: 手动提交 1: 自动提交,默认)

    2. 确认当前提交方式 select @@autocommit;

    3. 提交事务 commit;

    示例验证

    表user,id为主键,name没有索引

    示例1

    事务1
      set @@autocommit = 0; //步骤1
      select * from user where id = 1 for update; // 步骤4
      commit; // 步骤7
    
    • 1
    • 2
    • 3
    • 4
    事务2
     set @@autocommit = 0; // 步骤2
     select * from user where id = 2 for update; // 步骤5
     commit; // 步骤8
    
    • 1
    • 2
    • 3
    • 4
    事务3
     set @@autocommit = 0; // 步骤2
     update user set name = '12' where id = 1; //步骤6
     commit; //步骤9
    
    • 1
    • 2
    • 3
    • 4

    步骤1~9按照顺序执行,我们可以看到:
    步骤7没有执行,步骤6会一直等待;步骤5不需要等待步骤7,可以看到这里是行锁。

    请添加图片描述

    示例2

    事务1
      set @@autocommit = 0; //步骤1
      select * from user where name = '123' for update; // 步骤4
      commit; // 步骤7
    
    • 1
    • 2
    • 3
    • 4
    事务2
     set @@autocommit = 0; // 步骤2
     select * from user where name = '456' for update; // 步骤5
     commit; // 步骤8
    
    • 1
    • 2
    • 3
    • 4
    事务3
     set @@autocommit = 0; // 步骤2
     update user set age = 12 where name = '123'; //步骤6
     commit; //步骤9
    
    • 1
    • 2
    • 3
    • 4

    步骤1~9按照顺序执行,我们可以看到:
    步骤7没有执行,步骤5,6会一直等待;和示例1的表现不一样,可以看到是表锁。

    再回顾一下结论: 悲观锁在非主键非索引时是表锁,在主键索引时是行锁。

    乐观锁

    乐观锁: 事务不加锁,不对读写加锁,更新时根据版本号或时间戳判断是否可以更新。

    例如表: user, 使用乐观锁,我们新加long型字段version。

     // 伪代码 
     public void update (long id) {
      // 查询
      User user = UserDao.selectbyId(id);
       // 一通业务操作
       do something 
    // 更新某个字段
    int res = update user set cols = xx, version = verison + 1 where id = xx1 and version = user.version;
     if (res != 1) {
       // 自旋重新执行业务,进行更新
     }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    我们可以看到乐观锁对比悲观锁,消耗的资源小,不影响其他业务。

    两者对比

    类型考虑冲突时间优点悲观
    悲观锁开始就考虑加锁能够严格保证同步效率低下
    乐观锁更新时才考虑效率较高自旋浪费cpu
  • 相关阅读:
    小新air14 2020 i5-1035G1完美黑苹果
    pcl基于最小切割的点云分割
    vue3 ref 和 reactive 区别
    python debug
    JS 实现AES方式加密数据实现示例
    [强化学习总结6] actor-critic算法
    java split分割去掉空值
    电脑重装Win11系统后如何修复音频录制
    Python连接Clickhouse遇坑篇,耗时一天成功连接!
    EdgeCloudSim官方Sample运行——Windows+IntelliJ IDEA+Matlab
  • 原文地址:https://blog.csdn.net/u013565163/article/details/126542468