隔离级别之可重复读级别解读

写在前面

本文主要从执行的sql表现出的现象上来分析’可重复读’这个隔离级别,鉴于底层还没了解透彻,就不涉及原理了。

注意:本次示例为Mysql 5.6.43

初始化SQL

CREATE TABLE `users` (
  `id` smallint(6) NOT NULL AUTO_INCREMENT,
  `name` varchar(25) DEFAULT NULL,
  `age` tinyint(4) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;

TRUNCATE users;
ALTER table `users` auto_increment=1;
INSERT INTO users(`name`,`age`) VALUES('lyf_16',16);
INSERT INTO users(`name`,`age`) VALUES('xtf_17',17);
SELECT * FROM users;

示例:事务a与事务b都是可重复读隔离级别

PS: 以下示例脚本是在2个会话中执行

#tx-a: 设置当前会话为REPEATABLE READ
SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ;
SELECT @GLOBAL.TX_ISOLATION AS 'GLOBAL-tx',@@SESSION.TX_ISOLATION AS '@@SESSION-tx';
	#tx-b: 设置当前会话为REPEATABLE READ
	SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ;
	SELECT @GLOBAL.TX_ISOLATION AS 'GLOBAL-tx',@@SESSION.TX_ISOLATION AS '@@SESSION-tx';
#tx-a: start
START TRANSACTION;
	#tx-b: start
	START TRANSACTION;

#以上事务谁先开始都没关系,不影响整体结果。重点在初始读开始于什么时候。

#tx-a: a1 :初始读
SELECT * FROM users;
-- 1 lyf_16	16
-- 2 xtf_17	17

	#tx-b: b2
	INSERT INTO users(name,age) VALUES('zbz',18);
	UPDATE users SET age=99 WHERE id=1;
	DELETE FROM users WHERE id=2;
	SELECT * FROM users;
	-- 1 lyf_16	99
	-- 3 zbz	18
	
#tx-a: a2 :tx-b事务未提交,tx-a未做任务增、删、改前的重复读,结果同a1
SELECT * FROM users;

	#tx-b: b3
	commit;
	
#tx-a: a3 :tx-b事务已提交,tx-a未做任务增、删、改前的重复读,结果同a1
SELECT * FROM users;

#tx-a: a4 :更新存在的数据(id=1),更新成功。但是age变成了最新提交的值(tx-b)。tx-a未变更的记录同a1
#这里读取的第一条记录包含了tb更新的99,与a1,a2,a3的读不一致了,即出现幻读
UPDATE users SET `name`='lyf_update' WHERE id=1;
SELECT * FROM users;
-- 1 lyf_update	99
-- 2 xtf_17		17

#tx-a: a5 :更新被其他事务(tx-b)删除了的数据,更新失败。查询结果同a4
UPDATE users SET age=88 WHERE id=2;
SELECT * FROM users;

#tx-a: a6:更新到其他事务(tx-b)新插入的数据,查询结果与a4不同;出现了初始读之后,非本事务(tx-a)插入的数据,即出现幻读
UPDATE users SET age=88 WHERE id=3;
SELECT * FROM users;
-- 1 lyf_update	99
-- 2 xtf_17		17
-- 3 zbz		88

#tx-a: a7
COMMIT;

总结如下:

  1. 当前事务自己的变更(增,删,改)如果成功(影响条数不为0),则当前事务的查询是可见的。

  2. 如果当前事务的成功(影响条数不为0)变更涉及到了其他已提交事务修改或者新增的记录,则当前事务此时的查询对这些修改或者新增也是可见的(即出现了幻读,)。

在此给出‘幻读’的解读就是:
幻读:出现非本事务变更的,与事务开始后初始读不一致的结果。

以上例子是在Mysql 5.6.43上执行的。至于5.7,5.8…等版本,需要自己去试验了。欢迎把试验后的结果一起交流。

  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值