oracle事务隔离级别_笔记6:多版本控制读一致性的含义
多版本控制读一致性的含义
我们已经看到了多版本控制机制如何提供非阻塞读,它不仅能提供一致(正确)的答案,还有高度的并发性。那还有什么不妥吗?除非了解到存在多版本控制机制,也知道多版控制的含义,否则事务就有可能完成得不正确。
一种会失败的常用数据仓库技术
许多人都喜欢用下面所述的这种常用的数据仓库技术
1)使用一个触发器维护源表中的一个LAST_UPDATED列
2)最初要填充数据仓库表时,要记住当前的时间,为此会选择源系统上的SYSDATE。例如,假设刚好是上午9:00
3)然后从事务系统中拉pull出所有行,这是一个完整的SELECT * FROM TABLE查询,可以得到最初填充的数据仓库。
4)要刷新这个数据仓库,他们要再次记住现在的时间。例如,假设已经过去了1个小时,现在源系统上的时间是上午10:00。他们会记住这一点。然后拉出自上午9:00以来修改过的所有记录,并把这些修改合并到数据仓库中。
现在数据仓库中有了自第一次执行拉出操作以来所修改的所有记录。确实可能有所有记录,但是也有可能不是这样。对于其他采用锁定系统的数据库来说,这种技术确实能很好地工作,在这些数据库中读会被写阻塞,反之写也会被读阻塞。但是在默认支持非阻塞读的系统中,这个逻辑是有问题的。
要看这个例子有什么问题,只需假设上午9:00至少有一个打开的未提交事务。例如,假设在上午8:59:30时,这个事务已经更新了表中我们想复制的一行。在上午9:00,开始拉数据时,会读取这个表中的数据,但是我们看不到对这一行所做的修改,而只能看到它的最后一个已提交的版本。如果在查询中到达这一行时它已经锁定,我们就会绕过这个锁。如果在到达它之前事务已经提交,还是会绕过它读取查询开始时的数据,因为读一致性只允许我们读取语句开始时数据库中已经提交的数据。在上午9:00第一次拉数据期间我们读不到这一行的新版本,在上午10:00刷新期间也读不到这个修改过的行。为什么呢?上午10:00的刷新只会拉出自那天早上上午9:00以后修改的记录,但是这个记录是在上午8:59:30时修改的。我们永远也拉不到这个已修改的记录。
那么,这是否意味着前面的逻辑就根本不能用呢?也不是,这只说明我们需要用稍微不同的方式来得到。应该查询V$TRANSACTION,找出最早的当前时间是什么,以及这个视图中START_TIME列记录的时间。我们需要拉出自最老事务开始时间(如果没有活动事务,则取当前的SYSDATE值)以来经过修改的所有记录。
select nvl(min(to_date(start_time,'mm/dd/rr hh24:mi:ss')),sysdate)
from v$transaction;
在这个例子中,就是上午8:59:30,即修改这一行的事务开始的那个时间。在上午10:00刷新数据时,会拉出自那个时间以来发生的所有修改,把这些修改合并到数据仓库中,这就能得到需要的所有东西。
本文来源 我爱IT技术网 http://www.52ij.com/jishu/5223.html 转载请保留链接。
- 评论列表(网友评论仅供网友表达个人看法,并不表明本站同意其观点或证实其描述)
-
