一、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;
(2) 然后我们在窗口2中尝试更新这条记录
C2:update my_new_mvc_test set name = ‘王爱国’ where id = 1;
我们会发现命令被卡住了,过一段时间会报错
分析:C2之所以被卡住,是因为C2在执行update前,试图对表加一个排他锁,而数据库规定同一资源上不能同时共存共享锁和排他锁。所以C2必须等C1提交并执行成功之后,释放了共享锁,才能加上排他锁,然后才能开始执行update语句。
(3) 当我们在窗口1中commit,提交这次事务的时候,锁被释放
(4) 然后在窗口2再次执行更新命令,会发现,执行成功了
(5) 在窗口2中也尝试加共享锁,发现可以执行成功
分析: C2读取的时候加共享锁成功,是因为同一资源,数据库允许存在多个共享锁
三、排它锁的使用
作用:MySql添加排它锁,排它锁是禁止别人读取,删除和更新这条资源
手动添加排它锁的命令是:(sql语句) + for update;
(1) 我们在窗口1中select一条数据并添加排它锁
(2) 在窗口2中也添加一个排它锁
(3) 发现命令被卡住,过一会会发现超时
分析:数据库不允许同一资源存在多个排它锁
注意:在窗口1中加了排它锁之后,在窗口2中依然可以使用
select * from my_new_mvc_test where id = 1;
查到数据,但是获取的只是加锁前的数据
四、应用场景
mysql加锁和索引有一定的关系,以上的处理中,id是主键,假如搜索的条件字段没有索引,那么数据库就需要扫描全表,但此时如果存在排它锁,就可能禁止读取需要的数据,导致部分数据扫描不到,从而导致语句阻塞,等待锁的释放,坏的情况还可能锁死表。
其他概念的一些理解:乐观锁、悲观锁是从是否锁数据方面进行分类,共享锁、排它锁是从锁的类型进行分类