MySQL隔离级别 repeatable

初级屌丝 发布于 2018/02/01 10:37
阅读 113
收藏 2

问题阐述:现在设置mysql的隔离级别位repeatable

T7这个事务里面有2个同样的select语句,T8事务有一个update语句

发生的顺序是:

T7开启事务

T7执行第一select语句

T8开启事务

T8执行update语句

T8提交事务

T7执行第二个select语句

T7提交事务

我想问下,T7第一个查询完之后,T8能更新成功吗?还是T7提交事务之后,T8才能更新?

求大神解答下

 

加载中
0
马铃薯头
马铃薯头

可重复读(Repeatable read):可重复读。  同一个事务的查询都是同事务开始时刻一致。

查询是不会对事务产生锁的。

可以通过select ... for update 来加锁,防止其他事务更新产生不一致数据。

另外可以通过 

SET  SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ;
SET  GLOBAL TRANSACTION ISOLATION LEVEL  REPEATABLE READ;

设置好后本地实际测试来模拟数据。

马铃薯头
马铃薯头
回复 @初级屌丝 : 这个我就不评论了,因为我本身也理解的不是很清楚。防止误导你。
初级屌丝
初级屌丝
回复 @阿井井 : 嗯,那他还是会从数据库查询,只不过查询的不是真正的数据库数据,而是中间带一个版本号的大概是中间数据那种对吧
马铃薯头
马铃薯头
回复 @初级屌丝 : 不是缓存,大概是mysql默认会记录一个version,会根据版本号去获取数据。这块的逻辑理解的不是很透彻,你可以查阅相关资料看下。
初级屌丝
初级屌丝
回复 @阿井儿 : 那T7第二次查询,是从哪查询的结果?缓存吗?他是怎么保持第一次和第二次查询数据一致的大神。
马铃薯头
马铃薯头
回复 @初级屌丝 : 是的,可以成功。而且事务T7第二次查询不会获取到T8更新的结果。 可重复读的隔离阶段保证的是,事务在开始和结束阶段获取到的数据一致。具体原理可以看下Mysql锁的实现机制了。 如果需要T7读取到T8修改的记录,可以修改事务隔离级别为Read Committed。
下一页
0
马铃薯头
马铃薯头

具体的话,你可以自己动手复现一次就好了。

CREATE TABLE `account` (
  `id` bigint(20) NOT NULL,
  `balance` int(9) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;

 

SET  SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ;

SELECT @@tx_isolation;

start TRANSACTION;

select * from account where id = 1

commit;

SET  GLOBAL TRANSACTION ISOLATION LEVEL  REPEATABLE READ;


SELECT @@tx_isolation;

start TRANSACTION;

select * from account where id = 1;


update account  set balance = 200 where id =1;

commit;

 

 

开启两个mysql窗口,分别按你的图片的事务顺序去执行就可以看到具体的结果。

马铃薯头
马铃薯头
回复 @初级屌丝 : 执行完查询后,不要去提交,在新窗口去执行第二个事务的数据。再返回第一个事务去执行查询
初级屌丝
初级屌丝
没法测啊?你第一个直接提交事务了,无法判断T7两个阶段的查询结果啊
返回顶部
顶部