1. Repeatable Read

REPEATABLE READ避免了不可重复读问题,事务内对同一数据的多次读取都是一致的。

一个事务修改一条数据,其他事务修改同一数据就要等待。

增、删数据时会出现幻读。

不可重复读的重点是修改数据,幻读的重点是增删数据。

事务各自COMMIT后,再查询,各自的修改内容就汇总在一起了。

 

2. 幻读(Phantom Read)

在Repeatable Read隔离级别下,一个事务可能会遇到幻读(Phantom Read)的问题。

幻读是指,在一个事务中,第一次查询某条记录,发现没有,但是,当试图更新这条不存在的记录时,竟然能成功,并且,再次读取同一条记录,它就神奇地出现了

 

 

3. 例子

我们仍然先准备好students表的数据:

mysql> select * from students;
+----+-------+
| id | name  |
+----+-------+
|  1 | Alice |
+----+-------+
1 row in set (0.00 sec)

然后,分别开启两个MySQL客户端连接,按顺序依次执行事务A和事务B:

时刻 事务A 事务B
1

// 设置隔离等级

SET TRANSACTION ISOLATION LEVEL REPEATABLE READ;

SET TRANSACTION ISOLATION LEVEL REPEATABLE READ;
2 BEGIN; BEGIN;
3  

// 查询没有

SELECT * FROM students WHERE id = 99;

4

// 插入一条数据Bob

INSERT INTO students (id, name) VALUES (99, 'Bob');

 
5 COMMIT;  
6  

// 再次查询也没有

// 因为Repeatable Read下在同一个事务内的查询都是与事务开始时刻一致,所以在B事务过程中是不会读到期间A中insert的值的

// REPEATABLE READ避免了不可重复读问题,事务内对同一数据的多次读取都是一致的。

SELECT * FROM students WHERE id = 99;

7  

// 更新成功

UPDATE students SET name = 'Alice' WHERE id = 99;

8  

// 再次读取,记录就有了

SELECT * FROM students WHERE id = 99;

9   COMMIT;

事务B在第3步第一次读取id=99的记录时,读到的记录为空,说明不存在id=99的记录。

随后,事务A在第4步插入了一条id=99的记录并提交。

事务B在第6步再次读取id=99的记录时,读到的记录仍然为空,但是,事务B在第7步试图更新这条不存在的记录时,竟然成功了,并且,事务B在第8步再次读取id=99的记录时,记录出现了。

可见,幻读就是没有读到的记录,以为不存在,但其实是可以更新成功的,并且,更新成功后,再次读取,就出现了。

 

 

4. 总结

  • 脏读:读到别的事务没有提交的数据。
  • 不可重复读:先前读取的数据,被别的事务改变了,再读就跟原来不一样了。
  • 幻读:第一次读的时候发现什么都没有,另一个事务偷偷放了东西进去,执行更新操作,再去访问的时候,发现有变化,惊讶地居然发现有东西了。

 

 

 

 

 

https://www.liaoxuefeng.com/wiki/1177760294764384/1245268672511968

Logo

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。

更多推荐