Oracle:如何找到模式中最后一次更新(任何表)的时间戳?
技术问答
271 人阅读
|
0 人回复
|
2023-09-14
|
有一个Oracle数据库模式(数据很小,但仍有10左右-15表)。它包含一种配置(路由表)。
' w! w3 d' k. M该架构必须不时轮询一个应用程序。通知将不会被使用。
1 z0 R3 O3 ^) w4 [! b4 l如果架构中的数据没有更新,应用程序应使用当前的内存版本。
H2 w' R/ }2 s2 L若任何表有任何更新,应用程序应将所有表重新加载到内存中。
7 h% @7 V) T' @" d( N1 D自给定关键点(时间或交易)ID)以来,更新整个架构最有效的方法是什么?
1 {1 |5 }& H+ O我猜想Oracle为每个架构保留一个事务ID。然后应该有这样的查询。ID将方法与下一轮询价进行比较。
2 R. ^+ _0 }0 D8 P我发现了这个问题,行级有这样一个伪列:7 f3 L0 M4 W( `- x
如何确定上次更新?Oracle表的时间
h2 G+ k& R7 f' j' [- f我认为在架构级别也存在类似的问题。: a$ ^) v7 T9 ]# m2 ?
有人能指出我的正确方向吗?
# ]. F+ ^& P$ n& c) n s; q1 v' T6 N8 b# {
解决方案: : R6 O0 z6 Q# F4 M% z" D
我不知道Oracle有任何这样的功能。 见下文。
" b2 r$ W) U$ Y" @+ c+ v我能想到的最好的解决方案是在每个表上创建一个触发器,以更新当前日期/时间的单行表或上下文。这种触发器可能在表级(而不是行级),因此它们的成本不会像大多数触发器那么大。
* Z, D+ @5 J! |顺便说一句,Oracle事务不能为每个架构保留ID,因为一个事务可能会影响多个架构。可以使用V
8 _8 s! S+ ]* J% n# Z% T `$ t$视图将事务跟踪回到受影响的对象,但这并不容易,几乎可以肯定其性能比触发方案差。6 A6 p0 T4 R- ^4 Z0 i
事实证明,如果你有10g,则可以使用Oracle闪回功能获取此信息。但是,您需要使用闪回功能(这本身会带来一些费用),并且查询速度非常慢(可能是因为它不是真正用于此目的):
- | S9 I7 Y& C/ C6 bselect max(commit_timestamp) from FLASHBACK_TRANSACTION_QUERY where table_owner = 'YOUR_SCHEMA and operation in ('INSERT','UPDATE','DELETE','MERGE')为了避免在上次更新表中锁定问题,您可能希望将更新放入使用独立事务的过程中,例如:
8 r* _" I; K2 C/ fcreate or replace procedure log_last_update aspragma autonomous_transaction;begin update last_update set update_date = greatest(sysdate,update_date); commit;end log_last_update;这将导致您的应用程序在一定程度上序列化:每个需要调用此过程的句子都需要等待,直到上一个句子完成。上次更新表也可能不同步,因为即使回滚激活触发器更新,表上的更新也会保留。最后,如果您的交易特别长,应用程序可能会在交易完成前选择新的日期/时间,以达不到目的。我对这个问题的思考越深,似乎就越不是一个好主意。7 _) t. p9 f7 Z3 |! O6 l: q. G' t& c
避免这些问题的更好解决方案是从触发器中插入一行。这不会锁定表,因此不会进行任何序列化或异步插入,因此它们可以与实际数据一起滚动(在应用程序看不见之前)。数据也可见)。应用程序将获得最大值。如果该表已建立索引,则最大值将非常快(事实上,该表将是索引组织表的理想候选人)。唯一的缺点是,您需要定期操作清除旧值,因此它不会变得太大。 |
|
|
|
|
|