这篇文章主要给大家介绍了关于乡邮投递路线与天主教;电阻隔离级别下索引和锁的测试脚本的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
基本概念
当前读与快照读
在MVCC中,读操作可以分成两类:快照读(快照读取)与当前读(当前读数).快照读,读取的是记录的可见版本(有可能是历史版本),不用加锁。当前读,读取的是记录的最新版本,并且对返回的记录,都会加上锁,保证在事务结束前,这条数据都是最新版本。
快照读:简单的挑选操作,属于快照读,不加锁(可序列化除外)。
select * from table where?
当前读:特殊的读操作,插入/更新/删除操作,属于当前读,需要加锁。
select * from table where?在共享模式下锁定;
select * from table where?进行更新;
插入表值();
更新表集?在哪里?
从哪里的表中删除?
隔离级别与加锁机制
未提交读取会发生脏读,不考虑。
已提交读取(钢筋混凝土)针对当前读,RC隔离级别保证对读取到的记录加锁(间隙锁定),存在幻读现象。
可重复读取针对当前读,RR隔离级别保证对读取到的记录加锁(记录锁定),同时保证对读取的范围加锁,新的满足查询条件的记录不能够插入(间隙锁定),不存在幻读现象。
可序列化所有的读操作均为退化为当前读,读写冲突,因此并发度急剧下降,不考虑。
测试脚本
-基本操作-
-查询事务隔离级别,默认是乡邮投递路线
显示类似" %isolation% "的变量;
-设置事务隔离级别为天主教;电阻
将会话事务隔离级别设置为已提交读取;
-数据初始化-
开始;
如果存在用户,则删除表;
创建表"用户"(
` id ' bigint(20)unsigned NOT NULL AUTO _ INCREMENT
“电子邮件”varchar(64)不为空,
“年龄”整数(11)不为空,
` address ' varchar(64)不为空,
主键(` id `),
唯一键` uniq_email` (`email `),
关键字` idx_age` (`age `)
);
插入到用户(电子邮件、年龄、地址)值(《test1@elsef.com》,18,《地址1》);
插入到用户(电子邮件,年龄,地址)值(《test2@elsef.com》,20,《地址二》);
插入用户(电子邮件、年龄、地址)值(“test3@elsef.com”,20,“地址3”);
提交;
从用户中选择*
-一、事务标识示例
开始;
从信息模式中选择处理标识TRX INNODB其中TRX _ MYSQL _线程_ ID=连接_ ID();
从用户中选择*
从信息模式中选择处理标识TRX INNODB其中TRX _ MYSQL _线程_ ID=连接_ ID();
显示引擎INNODB状态;
更新用户设置年龄=22,其中id=3;
-查询事务身份证明(识别)
从信息模式中选择处理标识TRX INNODB其中TRX _ MYSQL _线程_ ID=连接_ ID();
- INNODB引擎状态
显示引擎INNODB状态;
提交;
-二、可重复读、不可重复读示例
-第一次会议
将会话事务隔离级别设置为已提交读取;
开始;
-第二次会议
设置会话事务隔离级别可重复读取;
开始;
-第一次会议
从用户中选择*
-第二次会议
从用户中选择*
-第三次会议
开始;
插入用户(电子邮件、年龄、地址)值(‘test4@elsef.com’,30,‘地址4’);
提交;
-第一次会议这里因为是RC,所以可以读到trx3提交的新数据,这里如果是证明不可重复读的话应该使用更新而不是插入
从用户中选择*
提交;
-第二次会议这里因为是RR,所以不会读到trx3提交的新数据
从用户中选择*
提交;
-三、快照读幻读示例
-第一次会议
设置会话事务隔离级别可重复读取;
开始;
-这里使用快照读
从用户中选择*
-第二次会议
开始;
插入用户(电子邮件、年龄、地址)值(‘test4@elsef.com’,30,‘地址4’);
提交;
从用户中选择*
-第一次会议
从用户中选择*这里读不到测试4@的数据,因为是乡邮投递路线
-这里发生了幻读
插入用户(电子邮件、年龄、地址)值(' test4@elsef.com ',30,' address 4 ');-插入失败,因为电子邮件唯一索引冲突。
提交;
-四号。当前魔法阅读的例子
-钢筋混凝土
-第一次会议
将会话事务隔离级别设置为已提交读取;
开始;
-所有符合条件的年龄=20的记录将在此锁定。因为是RC,所以没有缝隙锁。
从年龄=20岁的用户中删除;
select * from user
-第二次会议
将会话事务隔离级别设置为已提交读取;
开始;
-因为trx1没有间隙锁,所以可以插入年龄=20的记录。
插入用户(电子邮件、年龄、地址)值(' test4@elsef.com ',20,' address 4 ');
select * from user-可以找到四条数据,可以读取trx1的删除数据。因为是RC,trx1没有提交,所以不影响trx2。
提交;
-第一次会议
select * from user-可以读取trx2新插入的数据。虽然当前正在读取trx1,但是没有添加相应的next-key锁,这并不妨碍trx2的新数据插入。
提交;
- RR
-第一次会议
设置会话事务隔离级别可重复读取;
开始;
从年龄=20岁的用户中删除;
select * from user
-第二次会议
开始;
-这里会被封,因为trx1在年龄=20左右加了间隙锁。
-非唯一索引。首先通过索引定位第一条满足查询条件的记录,在记录上添加X锁,在GAP上添加GAP锁,然后在主键聚集索引上添加记录X锁;
-然后读下一个并重复。转到第一条不符合条件的记录。这时候就不需要加记录X锁了,但是还是要加GAP锁,最后回到结尾。
插入用户(电子邮件、年龄、地址)值(' test4@elsef.com ',20,' address 4 ');
-直到超时,错误1205 (hy000):超过锁等待超时;尝试重新启动交易
-此时,如果查询可以看到三条记录。
提交;
-第一次会议
-此时只能看到一条记录,另外两条已被删除。
select * from user
提交;
-唯一索引RC
-第一次会议
将会话事务隔离级别设置为已提交读取;
开始;
从电子邮件='test3@elsef.com '的用户处删除;
-第二次会议
开始;
-可以看,因为trx1是RC
select * from user where email=' test3 @ elsef . com ';
-尝试更新此记录的年龄将会一直阻塞到超时,因为email是唯一被trx1锁定的索引,它还会锁定相应的主键索引。
-注意这里操作的id=3是trx1中操作的邮件的同一行记录。
更新用户设置年龄=40,其中id=3;
-第一次会议
提交;
-第二次会议
提交;
-无索引RC
-第一次会议
将会话事务隔离级别设置为已提交读取;
开始;
-由于地址字段没有索引,Innodb会锁定所有行,MySQL服务器会判断并释放锁。
从地址=“地址3”的用户处删除;
-第二次会议
将会话事务隔离级别设置为已提交读取;
开始;
-这一行会成功,因为这一行没有被锁定(先添加后释放)
更新用户设置年龄=10,其中地址=“地址2”;
-这一行也会被封锁,因为已经被trx1的语句锁定了,符合条件的都被锁定了。
更新用户设置年龄=10,其中地址=“地址3”;
-第一次会议
提交;
-第二次会议
提交;
-非唯一索引RR
-第一次会议
设置会话事务隔离级别可重复读取;
开始;
从年龄=20岁的用户中删除;
-第二次会议
设置会话事务隔离级别可重复读取;
开始;
-这里会被封锁,因为年龄=20的记录已经在trx1中被锁定,加了缺口锁,所以这里18已经落入锁定区间。
插入用户(电子邮件、年龄、地址)值(' test4@elsef.com ',18,' address 4 ');
-第一次会议
提交;
-第二次会议
提交;
-无索引RR
-第一次会议
设置会话事务隔离级别可重复读取;
开始;
-如果没有索引,表中的所有记录都将被锁定,主键索引上的所有间隙也将同时被锁定,以防止所有并发的更新操作。
从地址=“地址3”的用户处删除;
-第二次会议
设置会话事务隔离级别可重复读取;
开始;
-这里会被阻塞,因为主键已经被GAP锁定,所以新的insert无法成功执行。
插入用户(电子邮件、年龄、地址)值(《test4@elsef.com》,18,《地址四》);
-第一次会议
提交;
-第二次会议
提交;
-死锁简单示例
-第一次会议
开始;
从id=1的用户中删除;
-第二次会议
开始;
从id=3的用户中删除;
-第一次会议
从id=3的用户中删除;
-参见第2部分
-这里关系型数据库判断发生了死锁,中断了一个处理
-错误1213 (40001):尝试获取锁时发现死锁;尝试重新启动交易
从id=1的用户中删除;
-第一次会议
回滚;
-第二次会议;
回滚;
-五、死锁插入示例
如果存在t1,则删除表;
开始;
创建表t1(
` id` bigint not null auto _ increment,
主键(` id `)
);
插入T1级(一种通讯线路的名称)值(1);
插入T1级(一种通讯线路的名称)值(5);
提交;
从t1中选择*
-第一次会议
开始;
插入T1级(一种通讯线路的名称)值(2);
-会话2
开始;
-这里会阻塞
插入T1级(一种通讯线路的名称)值(2);
-第三次会议
开始;
-这里会阻塞
插入T1级(一种通讯线路的名称)值(2);
-会话1;
-此时回滚,trx2和trx3收到通知,MySQL自动中断一个trx,因为发生了死锁
-错误1213 (40001):尝试获取锁时发现死锁;尝试重新启动交易
回滚;
-第二次会议;
回滚;
-第三次会议;
回滚;
总结
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对我们的支持。
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。