【问题标题】:Oracle: simulating a "post-commit" triggerOracle:模拟“提交后”触发器
【发布时间】:2017-03-28 02:53:29
【问题描述】:

在向表中插入一些行后,如何获得相当于“提交时”触发器的功能?

在表中插入几行后,我想向外部进程发送一条消息,表明有行可以处理。使用语句级触发器会导致每次插入一条消息,我只想发送一条消息说“有要处理的行”。

【问题讨论】:

  • 发现队列存在 3 个问题:(1) 需要应用程序链接到 oracle 运行时,(2) 延迟时间超出我们的预期,以及 (3) 无法很好地扩展到计算场大小。
  • 似乎队列并不能解决基本问题...合并多个插入以便只生成一条消息。

标签: oracle


【解决方案1】:

创建工作。在提交发生之前,它实际上不会被提交。 (注意:DBMS_SCHEDULER 通常比 DBMS_JOB 好,但这种情况下需要使用旧的 DBMS_JOB 包。)

declare
  jobnumber number;
begin
  dbms_job.submit(job => jobnumber, what => 'insert into test values(''there are rows to process'');');
  --do some work here...
  commit;
end;
/

【讨论】:

  • 有没有办法可以使用它来合并插入?我想处理多个插入,然后执行一个“准备就绪”步骤。
  • 工作进展如何?在您控制的单个事务中(通过存储过程或其他东西),或者只是用户的简单插入语句?表级 AFTER 触发器会起作用吗?
  • 如果有很多您无法控制的事务,也许您可​​以将作业设置为未来一分钟,并让触发器检查 DBA_JOBS 中是否存在作业,这样他们就不会t 提交副本。
【解决方案2】:

由于您需要触发 外部 进程,请查看 DBMS_ALERT 而不是 DBMS_JOB。

外部进程将通过调用存储过程主动监听警报。在发出警报并提交警报后,存储过程将立即返回。

请注意,DBMS_ALERT 是一个序列化设备。因此,发出相同警报名称的多个会话将被阻塞,就像它们更新表中的同一行一样。

【讨论】:

  • 这是正确的答案,因为它允许合并多个插入。来自 Oracle Doc:“警报可以比相应的应用程序等待调用更频繁地发出信号。在这种情况下,旧的警报将被丢弃。应用程序总是获得最新的警报(基于事务提交时间)。”
【解决方案3】:

您可以设置一个标志来表示“我已发送消息”。 为了确保在提交时“重置”标志,使用 dbms_transaction.local_transaction_id 然后你可以简单地做一个

IF v_flag IS NULL OR dbms_transaction.local_transaction_id != v_flag THEN
  v_flag := dbms_transaction.local_transaction_id;
  generate message
END IF;

【讨论】:

    【解决方案4】:

    使用 Oracle Advanced Queuing,您可以使用队列表上的侦听器将记录数组排入队列。

    记录将加载,然后侦听器可以启动您希望的任何进程,甚至是 Web 服务调用

    http://download.oracle.com/docs/cd/B28359_01/appdev.111/b28419/d_aq.htm#i1001754

    【讨论】:

      猜你喜欢
      • 2011-04-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-08-27
      • 1970-01-01
      相关资源
      最近更新 更多