准备工作,先准备一张表
create table t3(id int not null primary key,value int,index(value)); insert into t3 values(1,0); insert into t3 values(2,3); insert into t3 values(3,5); insert into t3 values(4,7); insert into t3 values(5,20); insert into t3 values(6,41); insert into t3 values(7,51); insert into t3 values(8,61);
为了验证记录锁和间隙锁的存在,需要为两个字段添加一个主键索引(唯一索引)和普通索引
PS:因为只有该字段添加索引,当使用到该字段进行查找修改的时候才会有这两个锁的存在,没有默认为表锁【因为没用索引默认全表扫描,为了数据的安全性必须枷锁】
验证记录锁(需要使用唯一索引或者主键索引)
原理:因为使用唯一索引或者主键索引找数据的时候具有唯一性,查找的是一个确定的数据,当找到以后立刻停止继续检索,因此这里可以看出只需要锁住这行字段就行!!这就是行锁,而使用到普通索引的时候,因为普通索引找到是数据可能不唯一,因此需要锁住一块区域。
PS:唯一索引和普通索引有什么区别?
先看看查询操作两者的区别。
对于普通索引来说,查找到满足条件的第一个记录(5,500)后,需要查找下一个记录,直到碰到第一个不满足k=5条件的记录。
对于唯一索引来说,由于索引定义了唯一性,查找到第一个满足条件的记录后,就会停止继续检索。
验证记录锁开始:
开启两个客户端,同时连接同一张表
这里我开启两个黑窗口终端模拟两个客户机
数据如图所示:
准备工作完成:开始进入主题:验证记录锁
这里因为id为主键索引,因此我们查找数据利用id作为查找目标的根据
1.先进入事务
2.根据ID查找,再修改第一条记录
客户机一:update t3 set value = value+1 where id=1;
客户机二:update t3 set value = value+1 where id=3;
上面结果客户机二不会发生阻塞 (行锁锁的是id=1这个字段,和id=3无关)
客户机一:update t3 set value = value+1 where id=1;
客户机二:update t3 set value = value+1 where id=1;
上面结果客户机二会发生阻塞 (行锁锁的是id=1这个字段)
最终等待时间过长timeout
验证间隙锁(需要使用带普通索引的字段)
原理:间隙锁,顾名思义锁住一个字段的一段数据内容,可防止“幻读”
直接上操作验证:
1.两个客户端先进入事务begin;
2.
客户机一:update t3 set id = 20 where value=51;
客户机二:update t3 set id = 20 where value=41;
最终timeout