您当前的位置: 首页 >  数据库
  • 0浏览

    0关注

    1477博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

数据库学习笔记5-隔离级别 Repeatable Read

软件工程小施同学 发布时间:2021-02-24 23:31:49 ,浏览量:0

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事务B1

// 设置隔离等级

SET TRANSACTION ISOLATION LEVEL REPEATABLE READ;

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

// 查询没有

SELECT * FROM students WHERE id = 99;

4

// 插入一条数据Bob

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

 5COMMIT; 6 

// 再次查询也没有

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

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

SELECT * FROM students WHERE id = 99;

// 更新成功

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

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

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

关注
打赏
1665320866
查看更多评论
立即登录/注册

微信扫码登录

0.0465s