如何确保新的触发器不会搞砸现有进程

时间:2016-11-15 10:23:06

标签: oracle oracle11g triggers

背景:

  • 我们有一个(非常)成熟的遗留系统,它建立在Oracle数据库之上。
  • 我们需要添加一些触发器,在每组更新,插入或删除时,在一组指定的表中创建一个名为TBL_REPLICATION的表中的记录。
  • 无论发生什么,都不应该阻止执行现有功能。

我的意思是,如果写入TBL_REPLICATION存在问题(由于争用或其他原因),新触发器的操作失败并且记录将更可取写入TBL_REPLICATION而不是任何其他受影响的行为。

我们可以做什么 - 无论是在触发器中还是在他们将要写入的表中 - 使得对TBL_REPLICATION的写入某种程度不那么重要比现有的写入和读取(在其他表)?

我意识到"不那么重要"是一个含糊不清的术语,但我希望我已经掌握了我想要做的事情。

1 个答案:

答案 0 :(得分:1)

我要做的事情:

  1. 将关键表及其索引放在一个单独的表空间中,这样任何存储相关的问题都不会影响您的" main"数据。 (你可以把它放在一个单独的ASM磁盘组上,但它可能是一种过度杀伤)
  2. 关于"隔离"对关键表的写入操作,因此它不会影响(延迟/提高错误)主要"逻辑" - 我只是使用s{(\d+)(.)(\d+)}{ '$x' . $2 . $2 }ee 函数来生成一个单独的从属进程,它将执行所需的操作。请注意,由于操作不能连续执行,作为主流的一部分,但基本上与主流并行 - 您实际上可能不依赖于基表的特定状态和  #39;数据,在新关键表上执行任何操作时;但是,根据你的解释 - 它似乎不是一个问题。
  3. 无论哪种方式,如果您选择在单独的线程中运行此新表上的所有操作,或者如果您选择将它们作为主逻辑的一部分运行 - 包装逻辑非常重要在单独的PL / SQL块中,您只在异常部分中执行日志记录逻辑并继续执行(不允许代码崩溃)。这样你就可以确保在出现错误的情况下 - 它已被记录,但对主逻辑没有任何损害,后者继续执行。
  4. 注意: 请记住,触发器几乎总是一个不好的做法 - 它是一个PL / SQL代码,它在每次执行SQL之后运行(与触发器过滤器匹配)。这基本上意味着 - 在每次操作期间从SQL到PL / SQL引擎的上下文切换。这非常无效。如果您正在处理大量数据 - 您应首先尝试探索问题的其他解决方案。

    注意#2 : 我肯定会修改表格(如果它足够小 - 整个表格,如果它很大 - 最后/相关的少数分区)及其索引,那么他们就会使用它保持缓存,而不是缓冲区缓存(您必须首先使用dbms_job.submit设置Keep Cache的大小)。通过这种方式,它赢得了竞争"与其他对象'内存块,将始终缓存。 此外,我建议在进行任何更改之前使用OEM和AWR报告记录关键SQL语句的行为(资源消耗,执行计划),以便您可以轻松地比较它并确定所执行更改的效果。

    这是我在这件事上的两分钱。