关于mysql锁的一些基础知识后期再更新一篇博客,这里先直接进入锁等待的案例,不明白基础知识的读者请先去查找其他相关的博客学习以下。

关于mysql死锁可以查看笔者另外一篇文章:https://blog.csdn.net/LLF_1241352445/article/details/83472715

简单介绍下相关的sql:

show variables like "autocommit"  查看当前会话是否自动提交事务;
set autocommit = 0  设置当前会话为非自动提交事务  0:非自动提交事务,对应 OFF   1:自动提交事务,对应为 ON
show variables like "Innodb_lock_wait_timeout"  查看当前会话锁等待超时时间限制,默认为50S;
set Innodb_lock_wait_timeout = 5; 设置当前会话锁等待超时时间为5S
commit  提交当前会话的事务
案例1:两个不同session同时对满足条件的行数据进行update导致锁等待超时,此时抛出等待超时异常(即使使用的过滤条件不存在索引,也会陷入锁等待)

在sessionA开启非自动提交事务,设置set autocommit = 0;
sessionA执行update:update user_info set age = 11 WHERE name = 'session A update 21';此时相当于sessionA拥有了name为“session A update 21”的行数据的排他锁(X锁);
sessionB同样开始非自动提交事务:设置set autocommit = 0;
sessionB设置锁等待超时时间为5S,方便观察等待超时现象:set Innodb_lock_wait_timeout = 5;
sessionB同样执行update操作:update user_info set age = 12 WHERE name = 'session A update 21';因为更新的数据行和sessionA更新的数据行一致,且sessionA的事务还没提交,相当于排他锁还没释放,所以sessionB进入锁等待时间;
超过5秒后,sessionB出现锁等待超时i异常:Lock wait timeout exceeded; try restarting transaction,如图:

关于mysql锁等待及等待超时的详细案例( Lock wait timeout exceeded)_死锁
案例2:间隙锁【排他锁】导致的锁等待——在非自动提交事务的前提下,sessionA试图删除一条不存在的数据,产生间隙锁,此时sessionB试图insert一条间隙范围内的数据,处于锁等待;

表结构:user_info (primary key id,name,age key);  分析:id为Record Lock ,age为 next-key lock

已知存在age为12,20,30,35,50的数据;
session A 执行删除语句:delete from user_info WHERE age = 15;此时因为不存在age=15的数据,所以产生间隙锁,锁范围为[12,20];所以在sessionA事务未提交之前,不能对该为范围内的数据加锁,即不能进行update操作(包括 update,delete,insert);
session B执行insert操作:INSERT into user_info VALUES(REPLACE(UUID(),"-",""),"锁",18),结果:Lock wait timeout exceeded; try restarting transaction
分析:因为session A已经产生范围为[12,20]的间隙锁,此时插入的18在间隙锁范围内,必须等待sessionA提交事务或者等待锁超时异常进行事务回滚;