MySQL for update 用法解析

基本原理与用法

MySQL在查询语句后面加上 for update ,例如

select * from student where id = 1 for update;

即为手动给读操作加上写锁(或者说给共享锁再加上排它锁)。因为是写锁,如果在此之前有另一个事务对此数据加了写锁,那么当前的查询事务会等待写锁被释放(比如提交或回滚)后再查询。作为解决并发问题的方案之一。

for update nowait:被锁时直接报错而不等待。

for update wait 3:被锁时等待3秒,超过3秒后如果数据还存在写锁,则报错。

一定需要注意的点

for update是根据where的索引情况进行加锁,根据具体情况,可能会产生:行级锁、间隙锁、表级锁。

  • 当查询语句走主键/唯一键索引,且数据全部命中,锁住单行。(即使是范围查询,比如 where id in (1,2,3),如果都存在,也是只锁1,2,3三行)。
  • 当查询语句走主键/唯一键索引,但数据部分命中,或都不命中;或走非唯一索引:用间隙锁,锁住区间行。
  • 当查询语句不走索引,会用间隙锁把整张表锁住(但其实并不是表锁),因此要尽量避免索引失效的场景。

其他补充
间隙锁的范围:

假设数据是这样的

id name

2 a

6 b

9 c

如果对id=2的数据上间隙锁,则范围是:(-∞,2]、(2,6]

如果对id=6的数据上间隙锁,则范围是:(2,6]、(6,9]

如果对id=9的数据上间隙锁,则范围是:(6,9]、(9,+∞)

另外,开区间的范围是根据主键的排列顺序确定。

锁的介绍:

MyISAM是表级锁,InnoDB默认行级锁,也支持表级锁。

间隙锁只有在InnoDB的RR-可重复读、Serializable级别时才默认支持。

索引失效的常见场景:

联合索引时违背最左匹配原则

范围查询的范围过大,比如>=等范围条件的实际匹配量大、in后面行数较多。

各种语法待试验....面经里写的那些感觉有的不太对,如:

  • 有or必全有索引;
  • 复合索引未用左列字段;
  • like以%开头;
  • 需要类型转换;
  • where中索引列有运算;
  • where中索引列使用了函数;
  • 如果mysql觉得全表扫描更快时(数据少);
相关推荐
web2u3 小时前
MySQL 中如何进行 SQL 调优?
java·数据库·后端·sql·mysql·缓存
新知图书4 小时前
MySQL用户授权、收回权限与查看权限
数据库·mysql·安全
文城5214 小时前
Mysql存储过程(学习自用)
数据库·学习·mysql
沉默的煎蛋4 小时前
MyBatis 注解开发详解
java·数据库·mysql·算法·mybatis
C语言扫地僧4 小时前
MySQL 事务及MVCC机制详解
数据库·mysql
小镇cxy4 小时前
MySQL事物,MVCC机制
数据库·mysql
雾里看山5 小时前
【MySQL】 库的操作
android·数据库·笔记·mysql
꧁瀟洒辵1恛꧂6 小时前
从新手到高手的蜕变:MySQL 视图进阶全攻略
数据库·mysql
doubt。18 小时前
【BUUCTF】[RCTF2015]EasySQL1
网络·数据库·笔记·mysql·安全·web安全
小辛学西嘎嘎18 小时前
MVCC在MySQL中实现无锁的原理
数据库·mysql