在上篇文章中波及到了一个小小的问题,就是数据库事务的一致性视图是啥时候建设的?
这个问题还比拟重要,如果没搞清楚,可能会影响咱们做试验的后果,进而得出谬误的论断,所以明天松哥和大家简略聊一聊这个话题。
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. 小结
好啦,一个小小的案例,心愿小伙伴们在做试验的时候不要出错。本文波及到一个概念叫做一致性视图,如果大家不相熟能够参考上篇文章。