MySQL FOR UPDATE 锁级别

本文详细解析MySQL中FOR UPDATE锁的运作机制,包括其在不同情况下的锁级别,如表锁和行锁的区别。通过实例展示了在开启事务后,FOR UPDATE如何锁定数据,以及在非索引和索引字段查询时的不同表现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

MySQL FOR UPDATE 锁级别

标签(空格分隔): MySQL 表锁 行锁


MySQL FOR UPDATE 锁级别

结论

  1. 开启事务后,使用for update 会锁表,按照索引字段查询除外。
  2. 开启事务后,按照索引索引字段会锁住该行数据,其他不受影响。
  3. FOR UPDATE 是写锁,读操作不会锁住。
  4. 不开启事务,FOR UPDATE 不会锁任何数据

例子

现有如下记录表,其中user_id添加了索引。

#SELECT user_id,balance FROM tb_user_account for update;
+---------+---------+
| user_id | balance |
+---------+---------+
|      80 |       0 |
|      86 |      45 |
+---------+---------+

无锁

#连接1
SELECT user_id,balance FROM tb_user_account for update;
#连接2 仍然可以查询
SELECT user_id,balance FROM tb_user_account for update;

表锁

1.事务中查询非索引字段会锁表。
#连接1开启事务
START TRANSACTION;
#连接1查询非索引字段
SELECT user_id,balance FROM tb_user_account WHERE balance = 0 forUPDATE;
#连接2按索引字段查询,被锁住。
SELECT user_id,balance FROM tb_user_account WHERE user_id = 86 for update;
#ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction

行锁

1.事务中查询索引字段会锁该行数据。
#连接1开启事务
START TRANSACTION;
#连接1查询索引字段 user_id = 86
SELECT user_id,balance FROM tb_user_account WHERE user_id = 86 forUPDATE;
#连接2按索引字段查询 user_id =86,被锁住。
SELECT user_id,balance FROM tb_user_account WHERE user_id = 86 for update;
#ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction
#连接2按索引字段查询 user_id =80 ,未被锁住。
SELECT user_id,balance FROM tb_user_account WHERE user_id = 80 for update;
+---------+---------+
| user_id | balance |
+---------+---------+
|      80 |       0 |
+---------+---------+

E450 i5 16g 性能测试

一个用户50条

CAS
耗时:7257 1-11
耗时:7713 11-22
耗时:7408 23-34

悲观锁
耗时:15610 0-50
耗时:15848 50-100


每个用户10条

悲观锁
耗时:6092
耗时:7023
耗时:6300

CAS
耗时:5381
耗时:5555
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值