SELECT ... FOR UPDATE 到底是锁表还是锁行?

对于 SELECT … FOR UPDATE 我们知道除了有查询的功能外,还会对查询结果进行加锁,而且是悲观锁。

那么它到底是「行锁」还是「表锁」,这就要根据具体的使用场景来区分了,如下:

  1. WHERE 条件中有使用「主键」或者「索引」的话,那就是 行锁
  2. WHERE 条件中都是「普通字段」,那就是 表锁

这里拿 t_staff 表来简单举个例子,如下:

CREATE TABLE `t_staff` (
 `id` INT ( 11 ) NOT NULL AUTO_INCREMENT,
 `code` VARCHAR (25) NOT NULL,
 `name` VARCHAR ( 255 ) NOT NULL,
  PRIMARY KEY ( `id` ),
  KEY `idx_code` ( `code` ) USING BTREE 
) ENGINE = INNODB AUTO_INCREMENT = 1 DEFAULT CHARSET = utf8

我们可以看到,上边这个 t_satff 表:

  • 主键为 id
  • 字段 code 上加了唯一索引

为了更好的说明后边的例子,在 t_staff 表中 INSERT 一些数据:

mysql> SELECT * FROM t_staff
+----+----+----+
|  id  |  code  |  name  |
|  1  |  001  |  小一  |
|  2  |  002  |  小二  |
|  3 |  003  |  三三  |
|  4  |  004  |  小四  |
|  5  |  005  |  小五  |
|  6  |  006  |  小六  |
|  7  |  007  |  小七  |
+----+----+----+

OK,数据都准备好了!让我们通过下边三个场景来简单说明下 FOR UPDATE 到底是「行锁」还是「表锁」。

  1. WHERE 中使用主键

    mysql> SELECT * FROM t_staff WHERE id = 1 FOR UPDATE
    

    只锁定 id=1 的数据,行锁,此时除该条数据以外都允许 update。

  2. WHERE 中使用带索引的字段

    mysql> SELECT * FROM t_staff WHERE code = ’007’  FOR UPDATE
    

    只锁定 code=007 的数据,行锁,此时除该条数据以外都允许 update。

  3. WHERE 中使用普通字段

    mysql> SELECT * FROM t_staff WHERE name = ’三三’  FOR UPDATE
    

    由于 name 不是主键也没加索引,所以是表锁,所有数据此时都不能 update。

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

cab5

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值