Vla*_*hev 8 sql oracle schema timestamp sql-update
有一个Oracle数据库模式(数据非常小,但仍然有大约10-15个表).它包含一种配置(路由表).
有一个应用程序必须不时轮询此架构.不得使用通知.
如果架构中没有更新数据,则应用程序应使用其当前的内存中版本.
如果任何表有任何更新,应用程序应将所有表重新加载到内存中.
从给定的关键点(时间或事务ID)开始,检查整个模式以进行更新的最有效方法是什么?
我想象Oracle会为每个架构保留一个事务ID.然后应该有一种方法来查询这样的ID并使其与下次轮询进行比较.
我发现了这个问题,在行级别上存在这样的伪列:
我认为在架构级别上存在类似的东西.
有人可以指点我正确的方向吗?
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,如果表被索引,则应该非常快(实际上,此表将是索引组织表的理想候选者).唯一的缺点是你想要一个定期运行的工作来清理旧值,所以它不会变得太大.
| 归档时间: |
|
| 查看次数: |
62541 次 |
| 最近记录: |