我可以设置挂钩更改或添加表中的某些行并在发生此类事件时以某种方式得到通知吗?我发现了网络,只卡在管道上。但是没有办法在发送时立即获取管道消息。只有定期尝试接收。
5 回答
通常应避免从数据库实现观察者模式。
为什么?它依赖于供应商专有(非标准)技术,促进了数据库供应商锁定和支持风险,并导致了一些膨胀。从企业的角度来看,如果不以受控的方式完成,它可能看起来像“臭鼬工厂”——以一种不寻常的方式实现应用程序和集成模式和工具通常涵盖的行为。如果在细粒度级别上实施,它可能会导致与具有大量不可预测的通信和处理的微小数据更改紧密耦合,从而影响性能。机器中的一个额外齿轮可能是一个额外的断点——它可能对操作系统、网络和安全配置敏感,或者供应商技术中可能存在安全漏洞。
如果您正在观察应用管理的事务数据:
- 在您的应用程序中实现观察者模式。例如,在 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 服务。
在数据库本身中,您需要的是触发器。您可以在插入、删除、更新数据或其任意组合时运行任意 PL/SQL。
如果您需要让事件在数据库之外传播,您需要一种从 PL/SQL 触发器调用外部应用程序的方法。一些可能的选择是:
- DBMS_PIPES - Oracle 中的管道类似于 Unix 管道。一个会话可以写入,一个单独的会话可以读取以传输信息。此外,它们不是事务性的,因此您会立即收到消息。一个缺点是 API 是基于轮询的,所以我建议选项 #2。
- Java - PL/SQL 可以调用任意 Java(假设您将类加载到数据库中)。这为执行您想要的任何类型的消息传递打开了大门,包括使用 JMS 将消息推送到消息队列。根据您实现这一点的方式,您甚至可以将其与 INSERT/UPDATE/DELETE 语句本身进行事务绑定。然后,监听应用程序将只监听 JMS 队列,它根本不会与发布事件的数据库绑定。
查看 DBMS_ALERT、DBMS_PIPE 或(最好是)AQ(高级队列)它是 Oracle 的内部消息传递系统。Oracle 的 AQ 有自己的 API,也可以像 Java JMS 提供者一样对待。
还有像 Stream 或 (XStream) 这样的技术,但这些技术非常复杂。