网络错误时插入延迟并在dblink-table上插入触发器插入

时间:2011-11-30 21:27:45

标签: oracle

也许是一个奇怪的标题,我会试着解释一下。 我有两个Oracle服务器serverA和serverB。

  • 在serverA上我有一个表tabA,其中每一分钟都是一行 插入。
  • 在serverB上,我创建了一个具有相同功能的表tabB 结构为tabA。
  • 在serverA上,我创建了一个到serverB的dblink。上 serverA我创建了一个像
  • 这样的插入触发器

在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中删除数据也是如此。

有谁知道该怎么办?

3 个答案:

答案 0 :(得分:1)

首先,使用自定义触发器将数据从一个数据库复制到另一个数据库几乎肯定是一个坏主意。 Oracle提供了各种可帮助您实现复制的技术。尽管您还可以查看Streams或Golden Gate甚至更改数据捕获(CDC)之类的内容,但物化视图可能是最简单且最有可能的。自定义触发器会对触发插件的性能产生重大影响,并且会引入各种难以调试的故障情况。

由于在网络关闭时没有数据被插入tabA但是这些插入稍后出现,我倾向于怀疑引发了某种异常导致插入应用程序对插入进行排队直到稍后或者应用程序正在创建一个分布式事务,该事务涉及数据库B或某些其他资源,这些资源也受到网络错误的影响,直到某个稍后的某个时间点才能成功提交。由于我们对您的应用程序架构一无所知,因此很难进一步推测。您可以检查DBA_2PC_PENDING表以查看Oracle是否充当任何分布式事务的分布式事务协调器,但是还有许多其他软件组件可能充当事务协调器。

答案 1 :(得分:1)

如果两个数据库都是相似版本,则为Oracle高级队列。设置有点棘手,但异步消息传递模型将处理一个数据库或另一个数据库关闭的实例。

至于解决方案是否太复杂,我发现我简化了我在这里提出的问题。整个问题只有OP才能说清楚。这个问题看起来更像是一个消息传递问题还是合并数据?两种解决方案都比触发器工作得更好。

答案 2 :(得分:0)

  1. 您需要使用激活死连接检测 SQLNET.EXPIRETIME
  2. 我不建议您按照自己的方式进行复制。您可以使用“ON COMMIT REFRESH”物化视图来实现这种复制。