Oracle:如何查找架构中上次更新(任何表)的时间戳?

Vla*_*hev 8 sql oracle schema timestamp sql-update

有一个Oracle数据库模式(数据非常小,但仍然有大约10-15个表).它包含一种配置(路由表).

有一个应用程序必须不时轮询此架构.不得使用通知.

如果架构中没有更新数据,则应用程序应使用其当前的内存中版本.

如果任何表有任何更新,应用程序应将所有表重新加载到内存中.

从给定的关键点(时间或事务ID)开始,检查整个模式以进行更新的最有效方法是什么?

我想象Oracle会为每个架构保留一个事务ID.然后应该有一种方法来查询这样的ID并使其与下次轮询进行比较.

我发现了这个问题,在行级别上存在这样的伪列:

如何找出上次更新Oracle表的时间

我认为在架构级别上存在类似的东西.

有人可以指点我正确的方向吗?

All*_*lan 12

我不知道Oracle中有任何此类功能.见下文.

我能想到的最佳解决方案是在每个表上创建一个触发器,用于使用当前日期/时间更新单行表或上下文.这样的触发器可以在表级(而不是行级),因此它们不会像大多数触发器那样承载太多的开销.

顺便说一下,Oracle无法为每个模式保留事务ID,因为一个事务可能会影响多个模式.可能使用V $视图来跟踪事件回到它受影响的对象,但这并不容易,并且几乎肯定会比触发器方案更差.

事实证明,如果你有10g,你可以使用Oracle的闪回功能来获取这些信息.但是,您需要启用闪回(它带有一些自己的开销)并且查询速度非常慢(可能是因为它并不是真正用于此用途):

select max(commit_timestamp) 
from FLASHBACK_TRANSACTION_QUERY 
where table_owner = 'YOUR_SCHEMA' 
      and operation in ('INSERT','UPDATE','DELETE','MERGE') 
Run Code Online (Sandbox Code Playgroud)

为了避免"最后更新"表中的锁定问题,您可能希望将该更新放入使用自治事务的过程中,例如:

create or replace procedure log_last_update as
pragma autonomous_transaction;
begin
   update last_update set update_date = greatest(sysdate,update_date);
   commit;
end log_last_update;
Run Code Online (Sandbox Code Playgroud)

这将导致您的应用程序在某种程度上序列化:需要调用此过程的每个语句都需要等到上一个语句完成."上次更新"表也可能不同步,因为即使激活触发器的更新被回滚,其上的更新也将保持不变.最后,如果您有特别长的交易,应用程序可以在交易完成之前获取新的日期/时间,从而违背目的.我越是想到这一点,它看起来就越糟糕.


避免这些问题的更好解决方案就是从触发器插入一行.这不会锁定表,因此不会有任何序列化,并且不需要异步进行插入,因此它们可以与实际数据一起回滚(并且在应用程序之前不会显示数据也是可见的).应用程序将获得max,如果表被索引,则应该非常快(实际上,此表将是索引组织表的理想候选者).唯一的缺点是你想要一个定期运行的工作来清理旧值,所以它不会变得太大.