搜索

MySQL中select for update是锁表还是锁行

发表于 2025-11-05 01:15:24 来源:全栈开发

在并发一致性控制场景中,锁锁行我们常常用for update悲观锁来进行一致性的表还保证,但是锁锁行如果不了解它的机制,就进行使用,表还很容易出现事故,锁锁行比如for update进行了锁表导致其他请求只能等待,表还从而拖垮系统,锁锁行因此了解它的表还原理是非常必要的,下面我们通过一系列示例进行测试,锁锁行来看看到底是表还什么场景下锁表什么场景下锁行。

验证

1.示例说明

创建一个账户表,锁锁行插入基础数据,表还以唯一索引、锁锁行普通索引、表还主键、锁锁行普通字段4 个维度进行select ... for update查询,查看是进行锁表还是锁行。云服务器

2.表创建

创建一个账户表,指定account_no为唯一索引、id为主键、user_no为普通字段、curreny为普通索引:

复制CREATE TABLE `account_info` ( `id` int NOT NULL AUTO_INCREMENT COMMENT ID , `account_no` int NOT NULL COMMENT 账户编号, `user_no` varchar(32) NOT NULL COMMENT 用户 Id, `currency` varchar(10) NOT NULL COMMENT 币种, `amount` DECIMAL(10,2) NOT NULL COMMENT 金额, `freeze_amount` DECIMAL(10,2) NOT NULL COMMENT 冻结金额, `create_time` datetime(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) COMMENT 创建时间, `update_time` datetime(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6) COMMENT 修改时间, PRIMARY KEY (`id`) USING BTREE, UNIQUE KEY `uni_idx_account_no` (`account_no`) , KEY `idx_currency_` (`currency`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT=账户信息表;1.2.3.4.5.6.7.8.9.10.11.12.13.

插入基础数据:

复制insert into account_info values (1,1,ur001,RMB,100,0,now(),now()); insert into account_info values (2,2,ur002,RMB,1000,0,now(),now()); insert into account_info values (3,3,ur002,DOLLAR,200,0,now(),now());1.2.3. 3.根据主键查询

在事务 1 中,根据主键id=1 进行 for update查询时,事务2、事务 3 都进行阻塞,而事务 4 由于更新的id=2 所以成功,因此判定,根据主键进行 for update 查询时是行锁。

4.根据唯一索引查询

在事务 1 中,根据唯一索引account_no=1 进行 for update查询时,事务2、事务 3 都进行阻塞,而事务 4 由于更新的account_no=2 所以成功,因此判定,根据唯一索引进行 for update 查询时是行锁。

5.根据普通索引查询

在事务 1 中,根据普通索引currency=RMB 进行 for update查询时,事务2、服务器租用事务 3 都进行阻塞,而事务 4 由于更新的currency=DOLLAR`所以成功,因此判定,根据普通索引进行 for update 查询时是行锁。

6.根据普通字段查询

在事务 1 中,根据普通字段user_no=ur001 进行 for update查询时,事务2、事务 3 都进行阻塞,而事务 4查询的是user_no=ur002也进行阻塞,因此判定,根据普通字段进行 for update 查询时是表锁。

总结

如果查询条件是索引/主键字段,那么select ..... for update会进行行锁。

如果查询条件是普通字段(没有索引/主键),那么select ..... for update会进行锁表,这点一定要注意。

随机为您推荐
版权声明:本站资源均来自互联网,如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

Copyright © 2016 Powered by MySQL中select for update是锁表还是锁行,全栈开发  滇ICP备2023006006号-32sitemap

回顶部