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

 
  
 
  
您好,我是路人,更多优质文章见个人博客:http://itsoku.com

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

那么它加的是行锁还是表锁,这就要看是不是用了索引/主键。

没用索引/主键的话就是表锁,否则就是是行锁。

验证:

建表sql

//id为主键 
//name 为唯一索引
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,
 PRIMARY KEY ( id ),
    KEY idx_age ( age ) USING BTREE 
) ENGINE = INNODB AUTO_INCREMENT = 1570068 DEFAULT CHARSET = utf8

需要关闭自动提交,通过set @@autocommit=0; 设置为手动提交。0代表手动提交,1代表自动提交。

d3271f01824ee2f7548433ca2514becc.png

结合一下实例验证

实例1:

使用主键id为条件去查询,然后开启另一个事务去更新数据,更新被阻塞,加锁了,锁定要查询的id为1的行数据。

图一为第一个事务,并且没有提交事务

扫描二维码关注公众号,回复: 16335509 查看本文章

图二为第二个事务,去更新数据,被阻塞了

图三为第二个事务,长时间拿不到锁报错。

e6dd393540db79fa299ad6cbc0b7def3.png

9f10842beb8033ff018191e396083c5a.png

7f160cd531866a593d651c12c3849f72.png

实例2:

我们在开启一个事务对另一条id为2的数据进行更新,

2a72008280549a5b8b300408b9a4ca39.png

fd2faf738a7e72a06f80bae014cc943b.png

实例3(索引):

一开始的创建表就age创建了唯一索引。

ca56e90faaecccf84b76fbc999dc5a3f.png

98bebdd2e59a8be7b174f8af627bd833.png

3e6e0a7fd2a1a097e85fa2070fee6446.png

实例4:

使用普通的字段code去操作

d027ee7a54856ffe8dfcb627f1951268.png

70ec1551d08646e1329acdbfcd342646.png

cfed32ef5dae191a21de857650cff6eb.png

另一个事务我去更新另外一条数据,如果我更新成功了,就是锁行,失败了就是锁表。

26d6a43e36bd0ff6a48f19681bd5dc14.png

0bf955086c642c90da6fadd046eebd5a.png

结果:

如果查询条件用了索引/主键,那么select ..... for update就会进行行锁。

如果是普通字段(没有索引/主键),那么select ..... for update就会进行锁表。

更多好文章

  1. Java高并发系列(共34篇)

  2. MySql高手系列(共27篇)

  3. Maven高手系列(共10篇)

  4. Mybatis系列(共12篇)

  5. 聊聊db和缓存一致性常见的实现方式

  6. 接口幂等性这么重要,它是什么?怎么实现?

  7. 泛型,有点难度,会让很多人懵逼,那是因为你没有看这篇文章!

↓↓↓ 点击阅读原文,直达个人博客
你在看吗

猜你喜欢

转载自blog.csdn.net/likun557/article/details/132074125
今日推荐