文章目录

  • 介绍
  • 实例验证
    • 实例前准备数据
    • 实例1--验证通过主键索引查询会锁行
    • 实例2--验证通过普通索引作为查询条件会锁行
    • 实例3--验证查询条件不命中索引会锁表
    • 实例4--验证联合索引匹配到第一个字段也会锁行
    • 实例5--验证关联表情况下关联条件是索引会锁行
    • 实例6--验证关联表情况下关联条件不是索引只会锁行
  • 结论
  • 参考

介绍

select查询语句是不会加锁的,但是​​select …for update​​除了有查询的作用外,还会加锁呢,而且它是悲观锁。

在接触到这个语句之前,我一直认为它是加行锁的,但是我看有些文章是要看索引,因此我想做一个深入了解。

实例验证

实例前准备数据

user表

CREATE TABLE `user` (`id` int(11) NOT NULL AUTO_INCREMENT,`name` varchar(255) DEFAULT NULL,`age` int(11) DEFAULT NULL,`code` varchar(255) DEFAULT NULL,`prov_id` int(11) NOT NULL,`prov_code` varchar(100) DEFAULT NULL,PRIMARY KEY (`id`),KEY `idx_age` (`age`) USING BTREE,KEY `user_prov_id_IDX` (`prov_id`,`code`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=1570069 DEFAULT CHARSET=utf8;

prov_info表

CREATE TABLE `prov_info` (`id` int(11) NOT NULL AUTO_INCREMENT,`name` varchar(50) DEFAULT NULL,`code` varchar(10) DEFAULT NULL,PRIMARY KEY (`id`),KEY `prov_info_code_IDX` (`code`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=24 DEFAULT CHARSET=utf8;

user数据:

INSERT INTO test.`user`
(id, name, age, code, prov_id, prov_code)
VALUES(1, '测试1', 46, '0001', 21, 'K001');
INSERT INTO test.`user`
(id, name, age, code, prov_id, prov_code)
VALUES(2, '测试2', 20, '0002', 22, 'K002');
INSERT INTO test.`user`
(id, name, age, code, prov_id, prov_code)
VALUES(3, '测试3', 10, '0003', 23, 'K003');

prov_info数据

INSERT INTO test.prov_info
(id, name, code)
VALUES(21, '极阴岛', 'K001');
INSERT INTO test.prov_info
(id, name, code)
VALUES(22, '小环岛', 'K002');
INSERT INTO test.prov_info
(id, name, code)
VALUES(23, '中岛', 'K003');

在Dbeaver开启两个会话,分别作为事务1和事务2,设置事务1不自动提交

-- 关闭自动提交
select @@autocommit;set @@autocommit = 0;

实例1–验证通过主键索引查询会锁行

在事务1中对id=1,使用id作为查询条件,执行for update,不提交
在事务2中执行update语句
事务1:

select * from test.`user` u where u.id = 1 for update;

结果图:

事务2:(自动提交)

update test.`user` u set age = 46 where u.id = 1;
update test.`user` u set age = 20 where u.id = 2;

更新id=1的数据阻塞,更新id=2的数据没有阻塞

可以证明是锁行,如果是锁表的话,id=2的数据也会阻塞

实例2–验证通过普通索引作为查询条件会锁行

将之前事务提交。
在事务1中对id=3,使用age作为查询条件,执行for update,不提交
在事务2中执行update语句
事务1:

select * from test.`user` u where u.age = 10 for update;

结果图:
![在这里插入图片描述](https://img-blog.csdnimg.cn/301d7c88014a4031b516c0cd1ea496e8.png

事务2:(自动提交)

update test.`user` u set age = 20 where u.id = 2;
update test.`user` u set age = 20 where u.id = 3;

更新id=3的数据阻塞,更新id=2的数据没有阻塞

可以证明是锁行

实例3–验证查询条件不命中索引会锁表

将之前事务提交。
在事务1中对id=3,使用code作为查询条件,执行for update,不提交
在事务2中执行update语句
事务1:

select * from test.`user` u where u.code = '0003' for update;

结果图:

事务2:(自动提交)

update test.`user` u set age = 20 where u.id = 2;
update test.`user` u set age = 20 where u.id = 3;

更新id=3的数据阻塞,更新id=2的数据也会阻塞

由此可以证明是锁表

实例4–验证联合索引匹配到第一个字段也会锁行

这个实例跟实例2相同,只不过我想看看联合索引只匹配第一个字段是不是也可以锁行
事务1:

select * from test.`user` u where u.prov_id  = 23 for update;

事务2:

update test.`user` u set age = 20 where u.id = 2;
update test.`user` u set age = 20 where u.id = 3;

结果:
更新id=3的数据阻塞,更新id=2的数据没有阻塞

由此可以证明对于联合索引来说,只要命中了索引就可以锁行(联合索引要按顺序)

实例5–验证关联表情况下关联条件是索引会锁行

事务1:

select * from test.`user` u
inner join test.prov_info pi2 on u.prov_id = pi2 .id
where u.prov_id  = 23 for update;

事务2:

update test.`user` u set age = 20 where u.id = 2;
update test.`user` u set age = 20 where u.id = 3;
UPDATE test.prov_info SET name='小环岛', code='K002' WHERE id=22;
UPDATE test.prov_info SET name='中岛', code='K003' WHERE id=23;

结果:

user表id=2的数据没有阻塞,id=3的数据阻塞,是锁行
prov_info表id=22的数据没有阻塞,id=23的数据阻塞,是锁行

实例6–验证关联表情况下关联条件不是索引只会锁行

事务1:

select * from test.`user` u
inner join test.prov_info pi2 on u.prov_code = pi2 .code
where u.prov_id  = 23 for update;

事务2:

update test.`user` u set age = 20 where u.id = 2;
update test.`user` u set age = 20 where u.id = 3;
UPDATE test.prov_info SET name='小环岛', code='K002' WHERE id=22;
UPDATE test.prov_info SET name='中岛', code='K003' WHERE id=23;

结果:

user表id=2的数据没有阻塞,id=3的数据阻塞,是锁行
prov_info表id=22的数据没有阻塞,id=23的数据阻塞,是锁行

结论

如果查询条件命中了索引/主键,那么​​select … for update​​就会进行行锁。
如果是普通字段(没有索引/主键),那么​​select … for update​​就会进行锁表。

对于关联表的情况:
如果关联条件用到索引,那么关联表就会进行锁行
如果关联条件没有用到索引,那么关联表也会进行锁行
锁行只是跟另外一个关联相关联的行

参考

https://blog.51cto.com/javastack/4635681

select .... for update究竟锁表还是锁行?相关推荐

  1. 面试官问:select......for update会锁表还是锁行?

    欢迎关注方志朋的博客,回复"666"获面试宝典 select查询语句是不会加锁的,但是select .......for update除了有查询的作用外,还会加锁呢,而且它是悲观锁 ...

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

    select -for update 除了有查询的作用外,还会加锁呢,而且它是悲观锁.那它会加表锁还是行锁?相信很多人都知道这个结论:要看是不是用了索引/主键.没用索引/主键的话就是表锁,否则就是是行 ...

  3. select......for update会锁表还是锁行。

    select查询语句是不会加锁的,但是select .......for update除了有查询的作用外,还会加锁呢,而且它是悲观锁. 那么它加的是行锁还是表锁,这就要看是不是用了索引/主键. 没用索 ...

  4. select……for update会锁表还是锁行

    结果: 如果查询条件用了索引/主键,那么select - for update就会进行行锁. 如果是普通字段(没有索引/主键),那么select - for update就会进行锁表. 例如: 行锁例 ...

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

    select查询语句是不会加锁的,但是 select -for update 除了有查询的作用外,还会加锁呢,而且它是悲观锁. 那么它加的是行锁还是表锁,这就要看是不是用了索引/主键.没用索引/主键的 ...

  6. select......for update会锁表还是锁行?

    select查询语句是不会加锁的,但是select .......for update除了有查询的作用外,还会加锁呢,而且它是悲观锁. 那么它加的是行锁还是表锁,这就要看是不是用了索引/主键. 没用索 ...

  7. oracle update 锁表还是锁行,for update造成的Oracle锁表与解锁

    我遇到的情况: 当使用select语句查询表时,后面跟着for update , select * from table for update 当修改表中数据,但是没有commit就关掉PL/SQL, ...

  8. Oracle锁表 行级锁 表级锁 行级锁

    2019独角兽企业重金招聘Python工程师标准>>> Oracle锁表  行级锁  表级锁 ---- 行被排他锁定 ----在某行的锁被释放之前,其他用户不能修改此行       ...

  9. mysql行级锁 表级锁 页级锁详细介绍_MySQL行级锁、表级锁、页级锁详细介绍

    页级:引擎 BDB. 表级:引擎 MyISAM , 理解为锁住整个表,可以同时读,写不行 行级:引擎 INNODB , 单独的一行记录加锁 表级,直接锁定整张表,在你锁定期间,其它进程无法对该表进行写 ...

最新文章

  1. ProLiant 服务器安装 Ret Hat Enterprise Linux AS 3 说明 (一)
  2. MyBatis知多少(6)表现层与业务逻辑层
  3. dubbo mysql_dubbo系列(四) 凑一下热闹 使用dubbo redis mybatis mysql 实现商品秒杀功能...
  4. 13-一对多左连接查询分步查询(查询所有客户及客户对应的订单)
  5. 5、URLConnection(2)
  6. (转)Python3异常-AttributeError: module 'sys' has no attribute 'setdefaultencoding
  7. 【Qt串口调试助手】1.3 - 重写ComboBox下拉框的鼠标点击事件,实现点击下拉框扫描可用串口
  8. 每日codewars题之判断一个数是否是水仙花数
  9. python中如何创建一个空列表_Python创建空列表的字典2种方法详解
  10. Socket TCP UDP
  11. LayaBox1.7.16 TiledMap 销毁的问题,TiledMap销毁后屏幕变灰,不能显示
  12. h2ouve下载 insyde_一种基于InsydeBIOS的BIOS更改方法及系统与流程
  13. 如何占用计算机大量内存,windows7内存占用率高如何处理_win7电脑内存占用过高怎么办...
  14. 锐目对讲机的使用方法详解
  15. 系统集成项目管理工程师高频考点(第二章)
  16. Dockerfile构建镜像并发布镜像
  17. 9个最佳的大数据处理编程语言
  18. Windows 10无法调节屏幕亮度
  19. 第七讲:1.物联网敲击桌面打开小台灯
  20. svn plugin for VS —— AnkhSvn-2.6.12735下载地址

热门文章

  1. (附源码)计算机毕业设计ssm个性化大学生图书推荐系统
  2. 大学生学游戏原画和3D建模哪个好
  3. 基于android的thinkpad平板电脑
  4. Linux下查看用户列表
  5. HARVEST基音检测算法
  6. 如何使用cubic快速重装linux系统
  7. 不可思议的《魔兽世界》
  8. 蓝鸟bluebird Promise库介绍
  9. WinInet 介绍
  10. mysql 修改端口 用户名密码_MYSQL修改端口及密码