MySQL 锁机制

时间:2022-12-26 08:02:20

MySQL 锁机制

表锁

读锁

查看哪些表被加锁了
语法:show open tables

添加读锁
read 读锁关键字 | write 写锁关键字
语法:lock table 表名 read

解锁
语法:unlock table

场景一

当查询一加了读锁后,查询一无法进行查询其它表

-- 给student添加读锁
lock table student read
-- 当我们再去查询user表时,直接报错
select * from user

MySQL 锁机制

场景二

当我们去修改时,也会报错,因为加的是读锁

update student set StudentName = '小花3' where Id = 1

MySQL 锁机制

场景三

查询二(新建查询)中可以去查询其它表,但是修改当前表会进入阻塞状态(一直进行查询,指到解锁之后)

MySQL 锁机制

update student set StudentName = 'XXX5' where Id = 1

MySQL 锁机制

总结

加了表锁之后,查询1无法进行查询其它表(相当于这次借的钱没还,下次又来借钱,肯定是不借),查询1不能修改当前已经被锁表和其它表,会导致报错,除非解锁后回复正常操作

在查询1加了表锁之后,查询2可以查询其它表,但不能修改其它表和当前已经锁的表,修改当前锁的表会导致一直阻塞,除非解锁后回复正常操作

写锁

场景一

--给student添加写锁
lock table student write;

查询一:可以查询当前student,但是不能查询其它表(user…)
MySQL 锁机制

场景二

查询一:可以修改当前表,不能修改其它表

update student set StudentName = 'XXX2' where Id = 1

场景三

查询二:不可以查询当前student,可以查询其它表(user…)

select * from student

MySQL 锁机制

总结

查询一添加写锁后,查询一:可以查询当前student,但是不能查询其它表(user…),查询一:可以修改当前表,不能修改其它表,查询二:不可以查询当前student,可以查询其它表(user…)
MySQL 锁机制

行锁

场景一

查询一和查询二分别设置关闭自动提交
语法:set autocommit = 0;
设置(打开)自动提交
语法:set autocommit = 1;
当查询一修改完数据后,查询二中无法进行查看

MySQL 锁机制
MySQL 锁机制

查询二:执行完commit后
查询一:执行完commit后,再次查询既可看到更新后的数据

MySQL 锁机制
MySQL 锁机制

场景二

当查询二修改数据后,未进行commit时,查询一不能修改当前查询二修改的那台未进行commit时的数据,否则导致阻塞,只能等待

MySQL 锁机制
MySQL 锁机制
只要当查询二commit后,查询一才能看到更改后的数据

总结

当双方同时修改同一行数据时,修改完后必须要进行手动提交commit,对方才可以看到你修改的数据,否则你修改完后,别人是看不到的,别人也无法修改当前这条数据,否则就会出现阻塞

间隙锁

间隙锁
当我们用范围条件检索数据,并请求共享或排他锁时,InnODB会给符合条件的已有数据记录的索引项加锁:对于键值在条件范围内但并不存在的记录
这种锁机制就是所谓的间隙锁(Next-Key锁)

缺点

当锁定一个范用键值之后,即使某些不存在的键值也会被无辜的锁定,而造成在锁定的时候无法插入锁定键值范围内的任何数据。在某些场景下这可能会对性能造成很大的危害(造成间隙锁后,锁定键值范围内的数据无法插入和修改)

MySQL 锁机制

如何锁定一行

当前查询一窗口的某行数据被锁定时,查询二窗口无法进行修改数据,当查询一修改完提交后,查询二可以修改

语法:selectfrom test_innodb_lock where a=8 for update
只需加上 for update 关键字即可

MySQL 锁机制