在 Oracle 数据库适配器中接收基于轮询的数据更改消息

适用于 Oracle 数据库的 Microsoft BizTalk 适配器支持通过轮询 Oracle 数据库接收基于轮询的数据更改消息。 适配器通过以下方式将消息传递到应用程序:

  • 执行 SQL SELECT 查询以确定数据是否可用于轮询。 可以将适配器配置为定期或持续执行 SQL SELECT 查询。

  • 对 Oracle 表或视图执行 SQL SELECT 查询,或者执行存储过程、函数或打包的过程和函数。

  • 在 Oracle 数据库上执行可选的轮询后 PL/SQL 代码块。 此代码块通常用于更新目标中查询记录上的字段,或将查询的记录移动到另一个表或视图。

  • 通过调用 POLLINGSTMT 操作或作为轮询操作公开的存储过程、函数或打包的过程和函数,在结果集中返回查询结果。

    适配器在 Oracle 事务中执行所有这些操作。

    适配器还允许你通过公开连接 URI 中的参数来接收同一 PollingId 应用程序中多个 Oracle 项目的数据更改消息。 此参数修改 POLLINGSTMT 操作的目标命名空间。

更改 POLLINGSTMT 的目标命名空间

可以通过在连接 URI 中设置 PollingId 查询字符串参数来修改 POLLINGSTMT 操作的目标命名空间。 如果在连接 URI 中指定了 , PollingId 则 Oracle 数据库适配器会将 参数中指定的 PollingId 字符串追加到 POLLINGSTMT 操作的默认目标命名空间: http://microsoft.lobservices.oracledb/2007/03/POLLINGSTMT。 不修改 POLLINGSTMT 操作的消息操作。

例如,如果指定了以下连接 URI: OracleDb://User=SCOTT;Password=TIGER@Adapter?PollingId=AcctActivity,则目标命名空间将是 http:/microsoft.lobservices.oracledb/2007/03/POLLINGSTMTAcctActivity

通过为每个 POLLINGSTMT 操作提供唯一的命名空间,可以接收应用程序中多个 Oracle 表和视图的数据更改消息。

有关 Oracle 数据库适配器连接 URI 的详细信息,请参阅 创建 Oracle 数据库连接 URI

使用绑定属性接收数据更改的消息

通过设置以下部分或全部绑定属性,将 Oracle 数据库适配器配置为接收数据更改的消息。

Binding 属性 默认 必需/可选
InboundOperationType 确保该值设置为 “轮询”。 轮询 必需。 如果未显式设置,将应用默认值。
PolledDataAvailableStatement 指定执行的 SELECT 语句,以确定是否有任何数据可用于轮询特定表。 指定的语句必须返回由行和列组成的结果集。 结果集第一个单元格中的值指示适配器是否执行为 PollingStatement 绑定属性指定的值。 如果结果的第一个单元格包含正值,适配器将执行轮询语句。 例如,此绑定属性的有效语句为:

Select * from <table_name>

注意: 不得为此绑定属性指定存储过程。 此外,此语句不得修改基础 Oracle 数据库。
SELECT 1 FROM DUAL 必需。 如果未显式设置,将应用默认值,这意味着无论要轮询的表是否包含数据,适配器都必须继续轮询。
PollingAction 指定轮询操作的操作。 可以使用使用适配器服务外接程序从为操作生成的元数据中确定特定操作的轮询操作。 Null 可选,用于使用 SELECT 语句轮询表和视图的操作。
PollingInterval 设置为希望适配器查询 Oracle 数据库的时间间隔(以秒为单位)。 此属性指定轮询间隔和轮询事务超时。如果对 Oracle 数据库) 指定了查询和轮询后语句,则该值应大于执行查询和轮询后 (语句所需的时间,以及客户端处理查询数据和返回轮询响应消息所花费的时间。 500 必需。 如果未显式设置,将应用默认值。
PollingStatement 指定以下任一项:

- 应对 Oracle 数据库执行的 SQL SELECT 语句。 此语句应包含 FOR UPDATE 子句。 有关 FOR UPDATE 子句的信息,请参阅本主题后面的 在 Polling 语句中指定 FOR UPDATE 子句

- 请求要轮询的包中的存储过程、函数或过程或函数的消息。
null 必需。 将 PollingStatement 设置为非 null 值将启用轮询。
PollWhileDataFound 指定 Oracle 数据库适配器是否忽略轮询间隔并连续轮询 Oracle 数据库(如果数据在要轮询的表中可用)。 如果表中没有数据可用,适配器将还原为按指定的轮询间隔执行 SQL 语句 False 必需。 如果未显式设置,将应用默认值。
PostPollStatement 设置为可选的 PL/SQL 代码块,该代码块在执行查询后,但在查询数据返回到客户端之前由适配器执行。 Null 可选。 如果未指定任何值,则不执行投票后语句。

注意

如果使用 WCF 服务模型或 WCF 通道模型,还必须设置 AcceptCredentialsInUri 绑定属性。

在轮询语句中输入 FOR UPDATE

如果使用 SELECT 语句作为轮询语句并执行影响 SELECT 语句中指定的行的轮询后语句,则必须在轮询语句中使用 FOR UPDATE 子句。 指定 FOR UPDATE 子句可确保轮询语句选择的记录在事务期间被锁定,并且轮询后语句可以对其执行任何所需的更新。

注意

在某些情况下,轮询语句和轮询后语句之间的时间窗口内,会向表中添加更多满足投票后语句条件的记录。 在这种情况下,投票后语句将更新满足条件的所有记录,而不仅仅是作为轮询语句的一部分选择的记录。

如果指定了轮询后语句,并且轮询语句不包含 FOR UPDATE 子句,你将遇到以下两个条件之一:

  • 如果将 TransactionIsolationLevel 设置为 ReadCommitted,则轮询后查询不会更新所选行。

  • 如果 TransactionIsolationLevel 设置为 Serializable,则执行投票后语句时,将发生以下目标系统异常 (Microsoft.ServiceModel.Channels.Common.TargetSystemException) :“ORA-08177 无法序列化此事务的访问”。 在这种情况下,必须设置 PollingRetryCount 绑定属性,以定义希望适配器重试同一事务的次数。

    有关如何设置事务隔离级别的说明,请参阅 使用 Oracle 数据库配置事务隔离级别和事务超时

    如果适配器客户端已配置为使用事务,并且适配器中的 UseAmbientTransaction 绑定属性的值设置为 True ,则会在事务中执行轮询和轮询后语句。

    使用 FOR UPDATE 选项的轮询查询的一个示例是:

SELECT * from EMP WHERE FLAG = 'Y' FOR UPDATE  

在轮询语句中输入 NOWAIT 子句

在某些情况下,并发线程访问要轮询的表,导致表中的争用过多。 这可能会导致轮询查询被阻止,以获取对表行的锁定。 如果使用 SELECT 语句作为轮询语句,则可能需要在 SELECT 语句中指定 NOWAIT 关键字 (keyword) 以及 FOR UPDATE 关键字 (keyword) 。 如果轮询查询尝试选择的行存在锁,这将导致适配器中的轮询查询执行立即返回。 在这种情况下,Oracle 通常会引发异常。 同样,适配器客户端可以使用 PollingInterval 绑定属性来指定时间间隔,在此时间间隔之后适配器客户端必须重试轮询数据。

使用 NOWAIT 选项的轮询查询的一个示例是:

SELECT * from EMP WHERE FLAG = 'Y' FOR UPDATE NOWAIT  

在轮询语句中输入 SKIP LOCKED 子句

在某些情况下,由于访问要轮询的表的并发线程,轮询查询中指定的 WHERE 子句的结果集中的某些行被锁定。 例如,轮询查询从表中返回 6 行;由于其他事务,这 6 行中有 4 行已被锁定。 在这种情况下,你可能想要指定 SKIP LOCKED 关键字 (keyword) 以及 FOR UPDATE 关键字 (keyword) ,以指示数据库尝试锁定 WHERE 子句指定的行,并跳过发现已锁定的任何行。 WHERE 子句中的未锁定行在事务期间被锁定,轮询后语句可以对其执行任何必需的更新,以便不再轮询这些行。 这可确保在解锁 WHERE 子句指定的所有行之前,不必等待接收轮询消息。

SKIP LOCKED 关键字 (keyword) 在多台计算机上具有轮询数据库中同一表的适配器客户端时非常有用。 可以通过配置轮询操作的方式在适配器客户端之间进行负载均衡,以便接收 WHERE 子句指定的、在该时间点解锁的行的基于轮询的数据更改消息,然后更新行以确保适配器客户端是否收到基于轮询的数据更改消息, 其他客户端不会收到相同的消息。

使用 SKIP LOCKED 选项的轮询查询示例是:

SELECT * from EMP WHERE FLAG = 'Y' FOR UPDATE SKIP LOCKED  

支持 FIFO) (有序传递

在生产环境中,轮询可用于监视 Oracle 数据库中的数据更改。 这些数据更改的消息由适配器客户端使用 Oracle 数据库适配器接收。 根据业务方案,适配器客户端必须按正确的顺序接收数据更改的消息。

Oracle 数据库适配器支持按顺序传递或先入先出 (FIFO) ,以保持从 Oracle 数据库接收消息的顺序。 下面是与在 Oracle 数据库适配器的入站方案中支持 FIFO 相关的一些注意事项。

  • 如果业务流程正在使用消息,则业务流程必须为来自 Oracle 数据库适配器接收端口的消息设置有序传递。

  • 如果在基于内容的路由) 方案中由发送端口 (使用消息,则发送端口必须为来自 Oracle 数据库适配器接收端口的消息设置有序传递。

    WCF-Custom 或 WCF-OracleDB 适配器具有 属性“失败时挂起请求消息 ”,该属性指定是否挂起入站处理失败的请求消息。 可以在 WCF-Custom 的“ 消息 ”选项卡上设置此属性,或者在 “错误处理 ”部分下 WCF-OracleDB 接收端口。 下表列出了根据是否设置此属性以及消息订阅服务器的状态 (业务流程或端口) 描述如何处理传入消息的方案。

Port 属性 处于“未登记”状态的订阅服务器 订阅服务器处于“已登记但已停止”状态
未设置失败属性时挂起请求消息 - 路由失败报告生成为挂起 (不可恢复的消息)

- 实际消息未暂停

- 事务中止时不执行后期轮询查询。 因此,轮询会重复并再次提取行。

- 事件日志中报告的错误,用于描述所发生的情况。
- 不被视为“失败”。 事件日志中没有错误消息。

- 实际消息将放入挂起 (可恢复) 队列中。

- 当订阅端口或业务流程启动时,消息会自动恢复。 如果在订阅服务器上设置了有序传递,则会接受该传递。

- 消息也可以手动恢复。
在设置失败属性时挂起请求消息 - 路由失败报告生成为挂起 (不可恢复的消息)

- 实际消息也已暂停

- 事务中止时不执行后期轮询查询。 因此,轮询会重复并再次提取行。

- 事件日志中报告的错误,用于描述所发生的情况。
- 不被视为“失败”。 事件日志中没有错误消息。

- 实际消息将放入挂起 (可恢复) 队列中。

- 当订阅端口或业务流程启动时,消息会自动恢复。 如果在订阅服务器上设置了有序传递,则会接受该传递。

- 消息也可以手动恢复。

另请参阅

开发 Oracle 数据库应用程序
使用 BizTalk Server 轮询 Oracle 数据库
使用 WCF 服务模型在 Oracle 数据库中接收基于轮询的数据更改消息
使用 WCF 通道模型在 Oracle 数据库中接收基于轮询的数据更改消息