mysql for update是锁表还是锁行

这篇具有很好参考价值的文章主要介绍了mysql for 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会进行锁表,这点一定要注意。

扫描下面的二维码关注我们的微信公众帐号,在微信公众帐号中回复◉加群◉即可加入到我们的技术讨论群里面共同学习。文章来源地址https://www.toymoban.com/news/detail-838931.html

到了这里,关于mysql for update是锁表还是锁行的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • mysql锁表原因及解决

    锁表发生在 insert、update、delete 中; 锁表的原理是数据库使用独占式 锁机制 ,当执行上面的语句时,对表进行锁住,直到发生 commit 或者 rollback 或者 退出数据库用户 ; 锁表的原因: A程序执行了对 table_1 的 insert、update、delete ,并还未 commit 时,B程序也对 table_1 进行 inser

    2024年02月09日
    浏览(28)
  • mysql什么情况下会锁表

    在MySQL中,当对表进行写操作(如INSERT、UPDATE、DELETE)时,需要对相关的数据行加锁以确保数据的一致性和完整性。在某些情况下,MySQL需要锁定整个表而不是部分行,这种情况下会锁定整个表,导致其他会话不能访问表。 1.使用ALTER TABLE、TRUNCATE TABLE等语句对表进行结构性修

    2024年02月12日
    浏览(29)
  • Mysql、Oracle 中锁表问题解决办法

    1. 确定锁定表的原因: 首先,需要确定是什么原因导致了表的锁定。可能的原因包括长时间的事务、大量的并发查询、表维护操作等。 2. 查看锁定信息: 使用以下命令可以查看当前MySQL数据库中的锁定信息: 3. 释放锁定: 如果确认某个会话或事务占用了表锁,可以考虑终止

    2024年02月12日
    浏览(59)
  • 最近不知道写啥,打算整理点儿关于钱币的文章,也转载点儿别人的技术文章,毕竟,洒家还是干技术滴嘛...

    最近开始整理之前陆陆续续买的乱七八糟的东西了,现在一堆东西还乱扔着呢~~ 先整理了一套大五帝钱还有下面这套清五帝。 清五帝钱一套: 27+宝泉局顺治通宝,铁壳锈 27.5康熙通宝满汉同 26.5宝泉局雍正通宝 三离划 26(卡)宝云局乾隆通宝 大耳隆 26+宝云局嘉庆通宝 大吉部

    2024年02月09日
    浏览(26)
  • 数据库update语句到底是行锁还是表锁?

    先说结论: 无索引的情况下,如果不走主键,那么update为表锁;有索引的情况下,走索引或者走主键(效果一样),那么update变为行锁。 大致把问题分为两种情况:有索引或者没有索引 先建一个没有索引的表,模拟一些数据,并且把事务自动提交关掉。 我们先在第一个查询

    2023年04月09日
    浏览(42)
  • 如何查看我的Ubuntu是x64还是arm

    在 Ubuntu 中,你可以使用以下命令来查看你的系统架构: 这个命令会输出你的系统架构。如果输出是 x86_64 ,那么你的系统是 64 位的 x86 架构(通常我们称之为 x64)。如果输出是 armv7l 或者以 arm 开头的其他值,那么你的系统是 ARM 架构。 另外,你也可以使用以下命令来获取更

    2024年02月14日
    浏览(31)
  • 【MySQL】说透锁机制(三)行锁升表锁如何避免? 锁表了如何排查?

    在上文我们曾小小的提到过,在 索引失效 的情况下,MySQL会把 所有聚集索引记录和间隙 都锁上,我们称之为 锁表 ,或叫 行锁升表锁 . 那么对于 行锁升表锁 ,有的同学误以为 行锁 升级变成了 表锁 ,但实际上 锁的类型并没有发生变化 ✍️, 还是行锁! 只是表的所有聚集

    2024年04月10日
    浏览(29)
  • 【用Percona Toolkit给mysql大表在不锁表的情况下建索引】

    共分为两步骤: 配置仓库 安装文档1 安装 安装文档2 由于mysql8默认使用的是caching_sha2_password,认证方式,而Percona Toolkit在centos7中使用的perl-dbd-mysql版本目前是4.023,暂时不支持这种认证方式,因此需要在mysql中新建一个以mysql_native_password认证的用户 建立索引 根据提示输入密码

    2024年02月07日
    浏览(27)
  • Invalid ON UPDATE clause for update_time column

    问题所在: 我在导入sql脚本的时候,没有成功导入,报的是Invalid ON UPDATE clause for ‘update_time’ column,在更新的时候表创建失败,于是我就查看了该错误,才发现我导入的sql脚本是高本版转储的sql脚本,我的 mysql版本比较低 , 所以会有这个错误 。 解决方案: 把原本的mysq

    2024年02月11日
    浏览(25)
  • MYSQL8修改root密码(转载)

    MYSQL8修改root密码 第一步:修改配置文件免密码登录mysql 1、进入文件:vi /etc/my.cnf 2、按i键表示可以编辑;添加skip-grant-tables;按esc键,输入:wq保存退出 3、重启mysql:sudo service mysqld restart 第二步免密码登录mysql 1、登录:mysql -u root -p 2、提示输入密码按回车进入 3、进入数据库,

    2023年04月27日
    浏览(28)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包