【问题标题】:Observer pattern in OracleOracle 中的观察者模式
【发布时间】:2013-04-11 09:30:07
【问题描述】:

我可以设置挂钩更改或添加表中的某些行并在发生此类事件时以某种方式得到通知吗?我发现了网络,只卡在管道上。但是没有办法在发送时立即获取管道消息。仅定期尝试接收。

【问题讨论】:

  • 这样的钩子通常被称为triggers
  • 您要通知谁(用户、应用程序...)?
  • @ChrisSaxon 一个连接到数据库的应用程序
  • 如果A对你有好处,你能接受吗? Q 仍然开放。

标签: database oracle design-patterns plsql pipe


【解决方案1】:

通常应避免从数据库实现观察者模式。

为什么?它依赖于供应商专有(非标准)技术,促进了数据库供应商锁定和支持风险,并导致了一些膨胀。从企业的角度来看,如果不以受控的方式完成,它可能看起来像“臭鼬工厂”——以一种不寻常的方式实现应用程序和集成模式和工具通常涵盖的行为。如果在细粒度级别上实施,可能会导致与具有大量不可预测的通信和处理的微小数据更改紧密耦合,从而影响性能。机器中的额外齿轮可能是额外的断点 - 它可能对操作系统、网络和安全配置敏感,或者供应商技术中可能存在安全漏洞。

如果您正在观察应用管理的事务数据:

  • 在您的应用程序中实现观察者模式。例如。在 Java 中,CDI 和 javabeans 规范直接支持这一点,按照 Gang Of Four 书的 OO 自定义设计是一个完美的解决方案。
  • 可选择向其他应用发送消息。过滤器/拦截器、MDB 消息、CDI 事件和 Web 服务也可用于通知。

如果用户直接修改数据库中的主数据,那么:

  • 在您的应用中提供一个单一的管理页面来控制主数据刷新或
  • 提供单独的主数据管理应用并向相关应用发送消息或
  • (最佳方法)根据质量(审查、测试等)和时间安排(与代码更改相同的处理方式)管理主数据编辑,通过环境进行推广,部署和刷新数据/将应用重新启动到托管程序

如果您正在观察由另一个应用程序管理的事务数据(共享数据库集成),或者您使用 ETL 等数据级集成为您的应用程序提供数据:

  • 尝试让数据实体仅由一个应用写入(其他应用只读)
  • 轮询暂存/ETL 控制表以了解更改发生的内容/时间或
  • 使用 JDBC/ODBC 级别的专有扩展进行通知或轮询,正如 Alex Poole 的回答中提到的那样,或者
  • 将来自 2 个应用的重叠数据操作重构为共享 SOA 服务,既可以避免观察要求,也可以将其从数据操作提升到更高级别的 SOA/应用消息
  • 使用 ESB 或数据库适配器调用您的应用程序进行通知或调用 WS 端点进行批量数据传输(例如 Apache Camel、Apache ServiceMix、Mule ESB、Openadaptor)
  • 避免使用数据库扩展基础设施,例如管道或高级队列

如果您使用消息传递(发送或接收),请通过您的应用程序执行此操作。来自数据库的消息是一种反模式。作为最后的手段,可以使用调用 Web 服务的触发器 (http://www.oracle.com/technetwork/developer-tools/jdev/dbcalloutws-howto-084195.html),但需要非常小心地以非常粗略的方式执行此操作,当一组数据更改时调用业务(子)流程,而不是处理细粒度的 CRUD 类型操作。最好触发一个作业并让该作业在事务之外调用 Web 服务。

【讨论】:

    【解决方案2】:

    除了其他答案,你可以看看database change notification。如果您的应用程序是基于 Java 的,则有特定的文档涵盖 JDBC,类似的 .NET herehere;还有一篇文章here

    你也可以看看continuous query notification,可以从OCI使用。

    我知道仅链接的答案不好,但我没有写任何东西的经验(我不得不承认我也没有使用过,但我一直想研究 DCN 一段时间现在...),这对于评论来说太长了*8-)

    【讨论】:

      【解决方案3】:

      在数据库本身中,您需要的是触发器。您可以在插入、删除、更新数据或其任意组合时运行任意 PL/SQL。

      如果您需要让事件在数据库之外传播,您需要一种从 PL/SQL 触发器调用外部应用程序的方法。一些可能的选择是:

      1. DBMS_PIPES - Oracle 中的管道类似于 Unix 管道。一个会话可以写入,一个单独的会话可以读取以传输信息。此外,它们不是事务性的,因此您会立即收到消息。一个缺点是 API 是基于轮询的,因此我建议使用选项 #2。
      2. Java - PL/SQL 可以调用任意 Java(假设您将类加载到数据库中)。这为执行您想要的任何类型的消息传递打开了大门,包括使用 JMS 将消息推送到消息队列。根据您实现这一点的方式,您甚至可以将其与 INSERT/UPDATE/DELETE 语句本身进行事务绑定。然后,监听应用程序将只监听 JMS 队列,它根本不会与发布事件的数据库绑定。

      【讨论】:

        【解决方案4】:

        根据您的要求使用triggersauditing

        【讨论】:

          【解决方案5】:

          查看 DBMS_ALERT、DBMS_PIPE 或(最好)AQ (高级队列),它是 Oracle 的内部消息传递系统。 Oracle 的 AQ 有自己的 API,但也可以像 Java JMS provider 一样对待。

          还有像 Stream 或 (XStream) 这样的技术,但这些技术相当复杂。

          【讨论】:

            猜你喜欢
            • 2016-02-20
            • 2023-04-10
            • 1970-01-01
            • 2013-02-12
            • 2014-10-14
            • 1970-01-01
            • 2016-08-15
            • 2011-03-30
            • 2015-09-07
            相关资源
            最近更新 更多