【问题标题】:Oracle: How to execute an insert trigger without delaying the insert response?Oracle:如何在不延迟插入响应的情况下执行插入触发器?
【发布时间】:2010-11-17 16:40:51
【问题描述】:

下面的触发器正在延迟我的插入响应。我怎样才能防止这种情况发生?

create or replace
TRIGGER GETHTTPONINSERT
BEFORE INSERT ON TABLENAME
FOR EACH ROW 
Declare
  --   
BEGIN
  -- The inserted data is transfered via HTTP to a remote location
END;

编辑人们告诉我做批处理作业,但我宁愿早点获得数据,也不愿获得 100% 的一致性。触发器的好处是数据一到就发生,但我承受不起插入响应延迟。

【问题讨论】:

  • 您应该知道,此传输要么是同步的,因此系统必须等待传输完成,要么是异步的,这意味着远程位置经常不同步。你不能同时拥有它。
  • 我会对异步选项感到满意,即使我失去了一些一致性
  • 我尝试了异步HTTP请求,但是响应时间还是一样
  • 我也在问自己同样的问题,最后我创建了一个为每个请求创建一个线程并立即响应的 Web Web 服务。

标签: oracle http plsql triggers


【解决方案1】:

显然,您可以通过删除触发器来防止延迟...... 否则,触发器将始终在插入之前执行,这就是 TRIGGER BEFORE INSERT 的用途。

或者您可以向我们详细说明您的具体需求?

【讨论】:

  • 如果触发器更改为插入后?它会解决我的问题吗?我需要将插入表中的所有数据传输到具有 HTTP 接口的远程位置
  • 好吧,因为 HTTP 事情会在插入之后触发,所以插入不会再被 HTTP 请求延迟。所以值得一试。
  • AFTER 触发器不会更好。所以插入了行,但没有提交,这样做有什么好处?
  • @Jader Dias,什么没用?它没有通过 HTTP 发送数据,出现某种错误或性能没有提高?
  • 插入时间没有降低到创建触发器之前的响应时间。
【解决方案2】:

一种方法是让触发器创建一个运行一次(每次)以执行 http 传输的 dbms_job。 dbms_job 创建相对较快,您可以将其视为有效地并行生成一个新线程。

有关更多信息,请参阅 http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:7267435205059 - 他的示例处理发送电子邮件,但想法是相同的。

【讨论】:

  • 触发器的优点是执行得更早,这对我来说很重要。
  • 如果您有足够的 job_queue_processes 可用,该作业将在没有明显延迟的情况下被拾取 - 但是,从触发器创建作业确实参与了整个事务,因此作业的创建将延迟到提交(但这主要是一件好事,因为回滚不会创建作业/启动传输)
  • 如果你在 10G 或以上,你可能会在使用 dbms_job 之前先看看作业调度程序,我还没有玩太多,但可能有更多选择,它是替代品对于 dbms_job。您还可以考虑使用排队或 dbms_pipe 来设置一个进程以几乎立即处理请求。
  • @Ethan - AQ 和管道当然是其他选择。不过要小心 dbms_scheduler,我相信在 10g 中它会在内部提交作为其处理的一部分,并且您不希望它出现在事务中间。
  • 是的,当您提交作业时,dbms_scheduler 会提交,而 dbms_job 不会。我真的认为你不应该在这种情况下使用 dbms_scheduler 。另请参阅asktom.oracle.com/pls/asktom/…
【解决方案3】:

也许您可以创建一个本地表来存储您必须传输的信息,并创建一个每 X 分钟执行一次的作业。从表中读取的作业,传输所有数据并从表中删除传输的数据。

【讨论】:

    【解决方案4】:

    难道不能使用 Oracle 复制选项吗?在语句触发器之后或之前,您可以通过 http 将插入的数据发送到远程位置。回滚时会发生什么?您的 hhtp 发送消息不会被回滚,因此您的数据不一致。

    【讨论】:

    • 不一致的数据在我的场景中不是问题
    • Oracle 复制需要哪种通信方式?它会在互联网上运行还是需要 VPN?
    • 您可以使用 Oracle Streams 同步两个或多个地理上分开的数据库,将使用互联网。
    【解决方案5】:

    对于这种确切情况有一个完美的解决方案,称为数据库更改通知。

    你几乎可以把它想象成一个异步触发器。

    您使用 DBMS_Change_Notification 包来告诉 oracle 要监视哪些表以及发生更改时要做什么。您可以监控 DML 和 DDL,您可以让 Oracle 批处理更改(即在触发前等待 10 次更改发生)。它将调用一个包含更改行的所有rowid的对象的存储过程......您可以决定如何处理,包括调用HTTP。插入提交不必完成。 Documentation for 10gR2

    【讨论】:

    • 谢谢!你在我的博客上发表评论后我看到了它
    【解决方案6】:

    如果您在 2020 年后遇到这个问题,请查看 DBMS_CQ_NOTIFICATION:

    https://docs.oracle.com/en/database/oracle/oracle-database/19/arpls/DBMS_CQ_NOTIFICATION.html

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-03-19
      • 1970-01-01
      • 2015-10-31
      • 1970-01-01
      • 1970-01-01
      • 2011-12-06
      • 2019-01-25
      • 1970-01-01
      相关资源
      最近更新 更多