一、MySql临时配置修改

首先我们打开两个命令行窗口,进入MySql命令行工作.

在两个窗口下都输入命令:set @@autocommit=0;

查看一下@@autocommit 是否为0

select @@autocommit;

这条命令是临时设置,只影响当前窗口,关闭之后,mysql配置没有变

因为mysql默认自动提交事务,我们需要卡住这条sql语句,这时mysql的锁会存在,使用另外一个命令行窗口进行测试了解详情

二、共享锁的使用

作用:共享锁允许其他人读取资源,但是禁止其他人删除,修改资源

MySql加共享锁的命令:(sql语句) + lock in share mode;

(1) 我们在窗口1中查询id为1的记录,并添加共享锁

C1:select * from my_new_mvc_test where id = 1 lock in share mode;

mysql 关联更新共享锁 mysql共享锁实现_mysql


(2) 然后我们在窗口2中尝试更新这条记录

C2:update my_new_mvc_test set name = ‘王爱国’ where id = 1;

mysql 关联更新共享锁 mysql共享锁实现_排它锁_02


我们会发现命令被卡住了,过一段时间会报错

mysql 关联更新共享锁 mysql共享锁实现_mysql_03


分析:C2之所以被卡住,是因为C2在执行update前,试图对表加一个排他锁,而数据库规定同一资源上不能同时共存共享锁和排他锁。所以C2必须等C1提交并执行成功之后,释放了共享锁,才能加上排他锁,然后才能开始执行update语句。

(3) 当我们在窗口1中commit,提交这次事务的时候,锁被释放

mysql 关联更新共享锁 mysql共享锁实现_mysql_04


(4) 然后在窗口2再次执行更新命令,会发现,执行成功了

mysql 关联更新共享锁 mysql共享锁实现_共享锁/排他锁_05


(5) 在窗口2中也尝试加共享锁,发现可以执行成功

mysql 关联更新共享锁 mysql共享锁实现_排它锁_06

分析: C2读取的时候加共享锁成功,是因为同一资源,数据库允许存在多个共享锁

三、排它锁的使用

作用:MySql添加排它锁,排它锁是禁止别人读取,删除和更新这条资源

手动添加排它锁的命令是:(sql语句) + for update;

(1) 我们在窗口1中select一条数据并添加排它锁

mysql 关联更新共享锁 mysql共享锁实现_共享锁/排他锁_07


(2) 在窗口2中也添加一个排它锁

mysql 关联更新共享锁 mysql共享锁实现_mysql_08


(3) 发现命令被卡住,过一会会发现超时

mysql 关联更新共享锁 mysql共享锁实现_共享锁/排他锁_09


分析:数据库不允许同一资源存在多个排它锁

注意:在窗口1中加了排它锁之后,在窗口2中依然可以使用

select * from my_new_mvc_test where id = 1;

查到数据,但是获取的只是加锁前的数据

四、应用场景

mysql加锁和索引有一定的关系,以上的处理中,id是主键,假如搜索的条件字段没有索引,那么数据库就需要扫描全表,但此时如果存在排它锁,就可能禁止读取需要的数据,导致部分数据扫描不到,从而导致语句阻塞,等待锁的释放,坏的情况还可能锁死表。

其他概念的一些理解:乐观锁、悲观锁是从是否锁数据方面进行分类,共享锁、排它锁是从锁的类型进行分类