观察者模式在Oracle中的实现

6

我能否在表格中更改或添加某些行时设置钩子,并在发生此类事件时以某种方式得到通知?我查阅了网络,但只找到了管道的相关内容。但是,当管道消息被发送时,没有立即获取管道消息的方法,只能定期尝试接收。


1
这种钩子通常被称为“触发器”。 - Egor Skriptunoff
你想要通知谁(用户、应用程序等)? - Chris Saxon
@ChrisSaxon 一个连接到数据库的应用程序 - kseen
如果 A 中的一个对你有用,你能接受它吗?问题仍然未决。 - Glen Best
5个回答

7

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

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

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

  • 在您的应用程序中实现观察者模式。例如,在Java中,CDI和javabeans规范直接支持此功能,而根据Gang Of Four书籍进行面向对象的自定义设计则是完美的解决方案。
  • 可选地向其他应用程序发送消息。过滤器/拦截器、MDB消息、CDI事件和Web服务也非常适用于通知。

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

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

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

  • 尽量让数据实体只由一个应用程序编写(其他应用程序只读)
  • 轮询暂存/ETL控制表以了解何时发生更改或使用JDBC/ODBC级别的专有扩展来进行通知或轮询,正如Alex Poole的回答所提到的那样
  • 将两个应用程序中重叠的数据操作重构为共享的SOA服务,可以避免观察要求,或将其从数据操作提升到更高级别的SOA/app消息
  • 使用ESB或数据库适配器调用您的应用程序进行通知,或使用WS端点进行批量数据传输(例如Apache Camel、Apache ServiceMix、Mule ESB、Openadaptor)
  • 避免使用数据库扩展基础设施,如管道或高级排队
如果您使用消息传递(发送或接收),请从您的应用程序中进行。 从数据库中发送消息有点反模式。 作为最后的手段,可以使用触发器来调用 Web 服务(http://www.oracle.com/technetwork/developer-tools/jdev/dbcalloutws-howto-084195.html),但是需要非常小心地以非常粗略的方式执行此操作,在数据更改时调用业务(子)进程,而不是压缩细粒度的 CRUD 类型操作。 最好触发一个作业,并在事务外部调用 Web 服务。

4
除了其他答案,您还可以查看数据库更改通知。 如果您的应用程序是基于Java的,则有特定的文档涵盖JDBC,类似于.NET 此处此处; 还有另一篇文章在这里
您还可以查看连续查询通知,该通知可从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队列,而不会与发布事件的DB绑定在一起。

2

2

看看DBMS_ALERT、DBMS_PIPE或者(最好的选择)AQ(高级队列),它是Oracle内部的消息系统。Oracle的AQ有自己的API,但也可以像Java JMS提供程序一样处理。

还有一些技术,如Stream或(XStream),但这些技术相当复杂。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接