一致性视图是啥时候建立的?

运维 数据库运维
数据库事务的一致性视图是啥时候建立的?这个问题还比较重要,如果没搞清楚,可能会影响我们做实验的结果,进而得出错误的结论,所以今天松哥和大家简单聊一聊这个话题。

 [[442041]]

在上篇文章中涉及到了一个小小的问题,就是数据库事务的一致性视图是啥时候建立的?

这个问题还比较重要,如果没搞清楚,可能会影响我们做实验的结果,进而得出错误的结论,所以今天松哥和大家简单聊一聊这个话题。

1. 错误演示

先给大家来一个错误演示。

我们打开两个会话窗口,默认情况下隔离级别是可重复读,我们来看下:

首先在 A 会话中查看当前 user 表,查看完成后开启事务:

可以看到当前 age 是 101。

接下来在 B 会话中修改 age:

可以看到,B 会话已经修改成功。

接下来回到 A 会话查询记录:

可以看到,A 会话的记录也变了。完整测试流程如下:

说好的可重复读呢?

按理说,可重复读就是别的事务对数据的操作不影响当前事务,但是上面这个案例似乎和我们理解的可重复读有出入。

2. 分析

不知道小伙伴们是否还记得可重复读的特点:

用户在另外一个事务中执行同条 SELECT 语句数次,结果总是相同的。

从这个角度来说,第一小节的案例似乎也没有问题,因为我们在 A 会话中执行 SELECT 语句多次,查到的结果也都是相同的,age 都是 102。

但是我们疑惑的是明明 B 会话的事务后开启的,但是我们却在 A 会话中读取到了 B 的修改,这似乎不应该。

这里就涉及到一个问题,事务的一致性视图是何时建立的?

事实上,我们执行的 begin 语句并不是一个事务真正的起点。执行完 begin 之后,接下来执行的第一句 SQL,事务才真正启动。

我们稍微修改一下第一小节的案例:

在 A 会话中,事务开启之后,立马先执行一条 SELECT 语句,然后再去 B 会话中做修改,修改完成后再回到 A 会话继续查询,此时发现 B 中的修改对 A 并不可见,这个结果也符合用户在另外一个事务中执行同条 SELECT 语句数次,结果总是相同的。

如果我们想要执行完 begin 之后,就立马开启事务,那么可以通过如下方式来执行:

  1. start transaction with consistent snapshot; 

这个 SQL 执行完之后,事务立马就启动了。

接下来,回到第一小节的案例,我们修改一下事务启动的命令:

此时,A 会话中事务的查询就看不见 B 中的修改了。

3.小结

好啦,一个小小的案例,希望小伙伴们在做实验的时候不要出错。本文涉及到一个概念叫做一致性视图,如果大家不熟悉可以参考上篇文章。

责任编辑:武晓燕 来源: 江南一点雨
相关推荐

2017-07-25 14:38:56

数据库一致性非锁定读一致性锁定读

2020-07-20 08:30:37

算法哈希分布式系统

2021-05-19 21:50:46

Hash算法测试

2021-07-27 08:57:10

算法一致性哈希哈希算法

2022-12-14 08:23:30

2021-02-05 08:00:48

哈希算法​机器

2021-02-02 12:40:50

哈希算法数据

2021-02-04 06:30:26

Python编程语言

2019-11-01 09:13:37

算法哈希缓存

2021-07-26 06:33:42

CRDT数据CAP

2020-11-24 09:03:41

一致性MySQLMVCC

2020-05-12 10:43:22

Redis缓存数据库

2021-06-22 10:22:08

业务IT一致性首席信息官

2022-03-22 09:54:22

Hash算法

2022-10-19 12:22:53

并发扣款一致性

2021-06-30 21:13:49

CPUCache数据

2020-04-01 15:50:17

TiDBMySQL数据库

2019-08-30 12:46:10

并发扣款查询SQL

2017-05-19 15:00:05

session架构web-server

2020-03-16 11:55:28

PaxosRaft协议
点赞
收藏

51CTO技术栈公众号