• select....for update会锁表还是锁行


    select …for update 除了有查询的作用外,还会加锁呢,而且它是悲观锁。那它会加表锁还是行锁?相信很多人都知道这个结论:要看是不是用了索引/主键。没用索引/主键的话就是表锁,否则就是是行锁。
    如果再进一步想,那对索引有无要求,唯一索引、主键索引、普通索引又或是组合索引、组合索引(命中左前缀索引部分),相信很多人就不大清楚了。下来我们就用具体的例子一个个场景来分析下。

    准备工作
    • 准备测试表test,如下:
      测试表
      主键:id;唯一索引组合: id_card,name: 唯一索引;name:普通索引

    • 准备测试数据,如下:
      测试数据

    • 关闭数据库自动提交
      在这里插入图片描述

    场景验证
    • 命中主键场景
      事务1
      查询id = 1数据并锁住在这里插入图片描述
      事务2
      更新id=1数据,提示该行数据被锁
      在这里插入图片描述
      更新id=2数据,提示更新成功
      在这里插入图片描述
      结论
      如果查询条件命中了主键,那么select … for update 会进行行锁

    • 命中普通字段
      事务1
      查询age=11数据并锁住在这里插入图片描述
      事务2
      更新age=11数据,提示该数据被锁
      在这里插入图片描述
      更新age=12数据,也提示该数据被锁
      在这里插入图片描述
      结论
      如果查询条件命中了普通,那么select … for update 会进行表锁

    • 命中唯一索引(组合索引全部字段)
      事务1
      查询id_card=id_01,name='test1’数据并锁住在这里插入图片描述
      事务2
      更新id_card=id_01,name='test1’数据,提示该数据被锁
      在这里插入图片描述
      更新id_card=id_02,name='test2’数据,提示更新成功在这里插入图片描述
      结论
      如果查询条件命中了唯一索引,那么select … for update 会进行行锁

    • 命中组合索引(部分字段)
      事务1
      查询id_card=id_01数据并锁住在这里插入图片描述
      事务2
      更新id_card=id_01数据,提示该数据被锁
      在这里插入图片描述
      更新 id_card=id_04数据,提示更新成功
      在这里插入图片描述

    结论
    如果查询条件命中了组合索引(部分字段),那么select … for update 会进行行锁

    • 命中普通索引
      事务1
      查询name=test1数据并锁住
      在这里插入图片描述
      事务2
      更新name=test1数据,提示该数据被锁
      在这里插入图片描述
      更新 name=test3数据,提示更新成功
      在这里插入图片描述
      结论
      如果查询条件命中了普通索引,那么select … for update 会进行行锁
    总结

    如果查询条件用了索引(无论是索引什么情况)/主键,那么 select … for update 就会进行行锁
    如果是普通字段(没有索引/主键),那么 select … for update 就会进行锁表。

  • 相关阅读:
    GBASE 8A v953报错集锦48--远程 rmt 导出 dual 表数据没有落到本地而是落到了集群节点上
    Shrio整合Jwt
    cesium示例教程100+目录
    huggingface连接不上的解决方案
    java计算机毕业设计扶贫平台MyBatis+系统+LW文档+源码+调试部署
    深入探索:AbstractQueuedSynchronizer 同步器的神秘面纱
    【计算机EI检索】2022年第六届视觉,图像与信号处理国际会议(ICVISP 2022)
    服务器被黑该如何查找入侵痕迹以及如何防御攻击
    谈谈最近招人的感受!
    前端开发:JS中==和===的对比总结
  • 原文地址:https://blog.csdn.net/m0_37774696/article/details/127471457