Mysql 中 select ... for update 加锁总结

新建一张表

复制代码
CREATE TABLE `stu` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(255) DEFAULT NULL,
  `age` int(11) DEFAULT NULL,
  `code` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `idx_age` (`age`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=1570068 DEFAULT CHARSET=utf8;

id 为主键, name和code为普通字段, age为索引字段.

插入两条测试数据如下:

(1) 以主键字段作为条件上锁

开启事物A 以id字段作为条件上锁, 操作如下

事务B执行更新 1001这条记录

操作超时更新失败.

而更新 1009 这条记录成功.

说明 以主键字段作为条件上锁,锁的是行,是表中查询命中的数据.

(2) 以索引字段作为条件上锁

开启事物A 以 age 字段作为条件上锁, 操作如下

事务B执行更新 1001这条记录

操作超时报错.

更新 1009 这条记录, 更新成功

说明和(1)一样, 以索引字段作为条件上锁, 锁住的是行, 是表中查询命中的数据.

(3) 以普通字段作为条件上锁

开启事物A, 以name字段为条件加锁

事物B更新 1001这条记录, 超时失败

再更新 1009 这条, 也是超时失败

说明, 以普通字段作为条件上锁, 锁的是表, 是表中的所有数据.

以下是三种情况的总结:

(1) 以主键字段作为条件上锁,锁的是行,是表中查询命中的数据

(2) 以索引字段作为条件上锁,锁的是行,是表中查询命中的数据

(3) 以普通字段作为条件上锁, 锁的是该表, 是表中的所有数据


and 和 or 组合条件

说明:

显示sql更新操作超时时间以及如何修改

在Navicat 中可以执行

show VARIABLES like 'innodb_lock_wait_timeout'; 显示更新操作超时时间

set innodb_lock_wait_timeout = 10; 可以修改超时时间, 单位是秒. 但是但是注意这种临时修改的方法只会在当前会话(也就是Navicat的一个查询) 中生效.

相关推荐
AI人工智能+电脑小能手1 小时前
【大白话说Java面试题 第87题】【Mysql篇】第17题:分布式事务的实现原理?
java·数据库·分布式·mysql·面试
yyuuuzz1 小时前
独立站的技术基础与常见运维问题
大数据·运维·服务器·网络·数据库·aws
来杯@Java2 小时前
图书管理系统(基于springboot+vue前后端分离的项目)计算机毕业设计java
java·spring boot·spring·vue·毕业设计·mybatis·课程设计
卷毛的技术笔记3 小时前
告别硬编码!Spring AI Alibaba 实现 AI Agent 智能工具调用(Tool Calling)
java·人工智能·后端·python·spring·ai编程
编程大师哥3 小时前
匿名函数 lambda + 高阶函数
java·python·算法
東雪木3 小时前
多线程与并发编程 专属复习笔记
java·开发语言·笔记·java面试
adrninistrat0r3 小时前
Java调用链MCP分析工具
java·python·ai编程
噜噜噜阿鲁~3 小时前
python学习笔记 | 11.3、面向对象高级编程-多重继承
java·开发语言
春生野草4 小时前
反射、Tomcat执行
java·开发语言
键盘上的猫头鹰4 小时前
【MySQL 教程(八)】索引、事务、用户管理、导入导出与分页查询
数据库·python·mysql