首页 > 数据库 >mysql for update是锁表还是锁行

mysql for update是锁表还是锁行

时间:2024-03-12 13:00:13浏览次数:29  
标签:account 事务 no 锁表 update 锁行 查询 索引

转载至我的博客 https://www.infrastack.cn ,公众号:架构成长指南

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

验证

示例说明

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

表创建

创建一个账户表,指定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='账户信息表';

插入基础数据

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

根据唯一索引查询

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

根据普通索引查询

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

根据普通字段查询

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

总结

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

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

扫描下面的二维码关注我们的微信公众帐号,在微信公众帐号中回复◉加群◉即可加入到我们的技术讨论群里面共同学习。

标签:account,事务,no,锁表,update,锁行,查询,索引
From: https://www.cnblogs.com/waldron/p/18068079

相关文章

  • rosdep update超时问题解决
    此问题的解决也适用ros11、初始化$sudorosdepinit2、下载rosdistro到本地$gitclonehttps://github.com/ros/rosdistro.git3、修改以下文件,将其url指向本地(1)文件1:20-default.list地址路径:/etc/ros/rosdep/sources.list.d/20-default.list原来内容:#os-specificl......
  • SQLIntegrityConstraintViolationException: Cannot add or update a child row: a fo
    异常原因:两张表存在外键关联并且有级联操作,级联更新或级联删除等1.(此处为)设置的外键与另一个表中的唯一索引列(一般是主键)中的值不匹配2.添加的外键列与另一个表的唯一索引列(一般是主键)的数据类型不同......
  • VMware vSphere 7 Update 3p 下载 (安全更新)
    VMwarevSphere7Update3p下载(安全更新)vCenterServer&ESXi,Dell,HPE,Cisco,LENOVO,FUJITSU,NEC,Inspur,HitachiCustomImage请访问原文链接:https://sysin.org/blog/vmware-vsphere-7-u3/,查看最新版。原创作品,转载请保留出处。作者主页:sysin.org服务器虚拟......
  • VMware ESXi 7.0 Update 3p 下载 - 领先的裸机 Hypervisor (安全更新)
    VMwareESXi7.0Update3p下载-领先的裸机Hypervisor(安全更新)VMwareESXi7.0Update3pStandard&AllCustomImageforESXi7.0U3InstallCD请访问原文链接:https://sysin.org/blog/vmware-esxi-7-u3/,查看最新版。原创作品,转载请保留出处。作者主页:sysin.org......
  • AutoUpdater.NET自动更新库使用
    原文链接:https://blog.csdn.net/g313105910/article/details/112313695.NET程序当部署很多的时候,每次手动下载升级麻烦,原来自己写了个自动升级的程序,独立运行,需要主程序来更新自动升级程序,自动升级程序升级主程序,功能运行正常,最近发现有AutoUpdater.NET库很方便,在此写下使用方法,......
  • AT_abc287_g [ABC287G] Balance Update Query 题解
    分析一眼分块。用值域分块来维护。先把所有的值离散化,使得至于不大于$n+q$。统计一下每个值的数量,每个块包含值的数量,每个块的价值和。修改值的时候先把原来值的数量,块包含的数量,块的价值剪掉被修改值的贡献,然后在新的值上面更新。修改数量直接改数量的变化贡献即可。找前$x$......
  • AT_abc287_g [ABC287G] Balance Update Query 题解2
    分析权值线段树。给每个节点赋一个值$val$和$a_i=val$的$b_i$之和。修改$a_x$的时候先将$a_x$的出现次数在树上剪掉$b_x$,再在$y$上面加上;修改$b_x$的时候直接加上变化量$y-b_x$。由于我们是要取前$x$大的$a_i$之和,在询问的时候有限考虑右儿子,然后在是当前......
  • VMware vSphere 8.0 Update 2b 下载 - Broadcom VMware 首次重大更新
    VMwarevSphere8.0Update2b下载-BroadcomVMware首次重大更新VMwarevSphere8.0Update2b下载-企业级工作负载平台2月29日(北京时间3月1日),VMwarebyBroadcom停更5个月后,终于发布了首次重大更新!ESXi8.0U2&vCenterServer8.0U2请访问原文链接:https:......
  • Balance Update Query
    link省选前写点简单题攒rp。显然每次选择,我们应该将所有物品从大到小排序,每次选择最大的\(x\)个。也就是每次要求前\(x\)大的数的和,随手写个平衡树可以做到这一操作,但是我不会,这里选择权值线段树来存贮每个数的个数,用线段树上二分解决前\(x\)大的数的和。注意离散化和......
  • IDEA更新本地代码丢失,IDEA使用Update Project更新本地代码丢失
    问题原因提交代码前,IDEA更新Git本地代码丢失,IDEA使用UpdateProject更新Git本地代码丢失,更新代码时执行UpdateProject操作。执行完该操作会发现IDEA没有任何提示,默认覆盖了你本地还未提交的代码,本地呕心沥血写的代码瞬间人间蒸发解决办法LocalHistory(本地历史更改记录)当出现......