也许是一个奇怪的标题,我会试着解释一下。 我有两个Oracle服务器serverA和serverB。
在A
create trigger tabA_trig
after insert on tabA
begin
insert into tabB@serverB(...) values(:new....,:new... etc);
exception
when others then null;
end tabA_trig;
创建此触发器后,每次将新行插入tabA时,都会在tabB中插入一个新行。
但是:当serverA和serverB之间的通信中断时,我没有收到任何错误(上面的例外情况就是这样),但是没有数据插入到tabA中!非常奇怪,更奇怪的是,大约15分钟后,新数据再次插入tabA。过了一会儿,丢失的数据开始填补漏洞,一段时间后没有数据丢失,插入按预期运行。
示例(tabA和tabB,第一列时间分钟和小时,第二列值):
Network OK:
tabA 1000 22;1001 22;1002 22
tabB 1000 22;1001 22;1002 22
Network ERROR:
About 15 minutes of no new data.
After 15 minutes:
tabA 1000 22;1001 22;1002 22;1017 22;1018 22;....
tabB 1000 22;1001 22;1002 22
After 30 minutes:
tabA 1000 22;1001 22;1002 22;1003 22;1004 22;1005 22;1006 22;1017 22;1018 22;....
tabB 1000 22;1001 22;1002 22
After 1 hour:
tabA 1000 22;1001 22;1002 22;1003 22;1004 22;1005 22;1006 22;1006 22;...;1017 22;1018 22;....
tabB 1000 22;1001 22;1002 22
如果我禁用了触发器,tabA上的插入会立即生效。
我使用触发器而不是物化视图的原因是我希望将所有已复制的数据保留到tabB,即使从tabA中删除数据也是如此。
有谁知道该怎么办?
答案 0 :(得分:1)
首先,使用自定义触发器将数据从一个数据库复制到另一个数据库几乎肯定是一个坏主意。 Oracle提供了各种可帮助您实现复制的技术。尽管您还可以查看Streams或Golden Gate甚至更改数据捕获(CDC)之类的内容,但物化视图可能是最简单且最有可能的。自定义触发器会对触发插件的性能产生重大影响,并且会引入各种难以调试的故障情况。
由于在网络关闭时没有数据被插入tabA
但是这些插入稍后出现,我倾向于怀疑引发了某种异常导致插入应用程序对插入进行排队直到稍后或者应用程序正在创建一个分布式事务,该事务涉及数据库B或某些其他资源,这些资源也受到网络错误的影响,直到某个稍后的某个时间点才能成功提交。由于我们对您的应用程序架构一无所知,因此很难进一步推测。您可以检查DBA_2PC_PENDING
表以查看Oracle是否充当任何分布式事务的分布式事务协调器,但是还有许多其他软件组件可能充当事务协调器。
答案 1 :(得分:1)
如果两个数据库都是相似版本,则为Oracle高级队列。设置有点棘手,但异步消息传递模型将处理一个数据库或另一个数据库关闭的实例。
至于解决方案是否太复杂,我发现我简化了我在这里提出的问题。整个问题只有OP才能说清楚。这个问题看起来更像是一个消息传递问题还是合并数据?两种解决方案都比触发器工作得更好。
答案 2 :(得分:0)