乐趣区

关于java:一致性视图是啥时候建立的

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

这个问题还比拟重要,如果没搞清楚,可能会影响咱们做试验的后果,进而得出谬误的论断,所以明天松哥和大家简略聊一聊这个话题。

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 之后,就立马开启事务,那么能够通过如下形式来执行:

start transaction with consistent snapshot;

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

接下来,回到第一大节的案例,咱们批改一下事务启动的命令:

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

3. 小结

好啦,一个小小的案例,心愿小伙伴们在做试验的时候不要出错。本文波及到一个概念叫做一致性视图,如果大家不相熟能够参考上篇文章。

退出移动版