图文详解MySQL的共享锁和排它锁

共享锁

又称为读锁,简称S锁。顾名思义,共享锁就是多个事务对于同一数据可以共享一把锁,都能访问到数据,但是只能读不能修改
加共享锁可以使用select ... lock in share mode语句

我们有如下测试数据:
图文详解MySQL的共享锁和排它锁_第1张图片
现在我们对id=1的数据行共享锁查询,这里会使用begin开启事务,而不关闭事务,这样做是用来测试,因为提交事务或回滚事务就会释放锁

共享锁sql分析实例

打开一个查询窗口

BEGIN;
SELECT * FROM area WHERE id=1 LOCK IN SHARE MODE

查询结果如下



此时我们没有提交事务,共享锁没有被释放。

实例1:
这时候我们新开一窗口,对id=1的数据行修改下数据试试
UPDATE area SET area_name='北京市2' WHERE id=1
运行结果如下:
图文详解MySQL的共享锁和排它锁_第2张图片
一直在运行中。原因是共享锁没有被释放

实例2:
这时我们再新开一个窗口,对id=1的数据行读取(不加锁机制)试试
图文详解MySQL的共享锁和排它锁_第3张图片
可以读取数据

实例3:
这时我们再新开一个窗口,对id=1的数据行读取(加读锁机制)试试

图文详解MySQL的共享锁和排它锁_第4张图片
也可以读取数据
由此得出以下结论:
1.共享锁的行不可以被修改(实例1)
2.共享锁的行可以不加任何锁读取(实例2)
3.共享锁的行可以加读锁读取(实例3)

排他锁

mysql InnoDB引擎默认的修改数据语句,update,delete,insert都会自动给涉及到的数据加上排他锁
select语句默认不会加任何锁类型,如果加排他锁可以使用select ...for update
加过排他锁的数据行
在其他事务中是不能修改数据的,
也不能通过for update和lock in share mode锁的方式查询数据,
但可以直接通过select ...from...查询数据,
因为普通查询没有任何锁机制

排他锁sql分析实例

打开一个窗口,现在我们对id=1的数据行排他查询
图文详解MySQL的共享锁和排它锁_第5张图片
此时我们没有提交事务,排他锁没有被释放

实例4:
新开一个窗口,对id=1的数据行排他锁方式读取试试
图文详解MySQL的共享锁和排它锁_第6张图片
一直在运行中。原因是排他锁没有被释放

实例5:
再新开一个窗口,对id=1的数据行共享锁方式读取试试
图文详解MySQL的共享锁和排它锁_第7张图片
一直在运行中。原因是排他锁没有被释放

实例6:
再新开一个窗口,对id=1的数据行进行普通查询试试
图文详解MySQL的共享锁和排它锁_第8张图片
可以读取到数据

由此得出以下结论:
1.排他锁的行不可以再加排他锁(实例4)
2.排他锁的行可以不加读锁(实例5)
1,2两点简化之排他锁的行不可以再加任何锁
3.排他锁的行可以普通读取(实例6)

共享锁与排他锁小结

排他锁与共享锁不能存在同一数据上
排他锁与排他锁也不能在同一数据上
共享锁与共享锁可以在同一数据上。
不用锁的查询可以读取加锁(共享锁,排他锁)的同一行数据

你可能感兴趣的:(MySQL)