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

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

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

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

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

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

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

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

更改 POLLINGSTMT 的目标命名空间

您可以通过在连接 URI 中设置 PollingId 查询字符串参数来修改 POLLINGSTMT 操作的目标命名空间。 如果在连接 URI 中指定了 PollingId ,Oracle Database 适配器会将参数中 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 Database 适配器连接 URI 的详细信息,请参阅 创建 Oracle Database 连接 uri

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

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

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

Select * from <table_name>

注意: 不得为此绑定属性指定存储过程。 此外,此语句不得修改底层 Oracle 数据库。
从双重选择1 必需。 如果未显式设置,则将应用默认值,这意味着适配器必须继续轮询,而不考虑正在轮询的表是否具有数据。
PollingAction 指定轮询操作的操作。 您可以使用 "使用适配器服务" 外接程序,从为操作生成的元数据中确定特定操作的轮询操作。 null 使用 SELECT 语句对表和视图上的轮询操作是可选的。
PollingInterval 设置为希望适配器查询 Oracle 数据库的时间间隔(以秒为单位)。 此属性指定轮询间隔和轮询事务超时。如果在 Oracle 数据库上指定了一个) ,则该值应大于执行查询和轮询后的 (语句所需的时间,以及客户端处理查询数据并返回轮询响应消息所需的时间。 500 必需。 如果未显式设置,则将应用默认值。
PollingStatement 指定以下项之一:

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

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

注意

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

在轮询语句中输入 FOR UPDATE

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

注意

您可以在 "轮询" 和 "轮询后" 语句之间的时间范围内,将更多记录添加到满足轮询后声明条件的表中。 在这种情况下,轮询后语句将更新满足条件的所有记录,而不只是作为轮询语句的一部分选择的记录。

如果指定了后期轮询语句,并且该轮询语句不包含 FOR UPDATE 子句,则将遇到以下两种情况之一:

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

  • 如果 TransactionIsolationLevel 设置为 可序列化,则在执行后续轮询语句时,将出现以下目标系统异常 (TargetSystemException) : "tnsnames.ora-08177 无法序列化此事务的访问权限"。 在这种情况下,你必须设置 PollingRetryCount 绑定属性,以定义你希望适配器重试相同事务的次数。

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

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

    带有 FOR UPDATE 选项的轮询查询的一个示例是:

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

在轮询语句中输入 NOWAIT 子句

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

带有 NOWAIT 选项的轮询查询示例如下:

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

在轮询语句中输入 SKIP 锁定子句

你可能会遇到这样的情况:由于并发线程访问正在轮询的表,因此会锁定轮询查询中指定的 WHERE 子句的结果集中的某些行。 例如,轮询查询将从表中返回6行;由于一些其他事务,已锁定这6行中的4行。 在这种情况下,您可能需要指定 SKIP lock 关键字以及 FOR UPDATE 关键字,该关键字指示数据库尝试锁定 WHERE 子句指定的行,并跳过任何已锁定的行。 WHERE 子句中的未锁定行在事务中被锁定,然后轮询后的语句可以对其执行任何所需的更新,以便不会再次轮询这些行。 这可确保无需等待接收轮询消息,直到 WHERE 子句指定的所有行都解除锁定。

如果在多台计算机上有适配器客户端在数据库中轮询同一个表,则 "跳过锁定" 关键字很有用。 您可以通过配置轮询操作来在适配器客户端之间实现负载平衡,方法是:对在该时间点解锁的 WHERE 子句所指定的行接收基于轮询的数据更改消息,然后更新该行,以确保如果适配器客户端收到基于轮询的数据更改消息, 其他客户端不会获得相同的消息。

使用 "跳过锁定" 选项的轮询查询示例如下:

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

支持按序送达 (FIFO)

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

Oracle Database 适配器支持按序送达或先进先出 (FIFO) ,以维护从 Oracle 数据库接收消息的顺序。 下面是与支持 Oracle Database 适配器的入站方案中的 FIFO 相关的几个注意事项。

  • 如果消息由业务流程使用,则该业务流程必须为来自 Oracle Database 适配器接收端口的消息提供按序送达集。

  • 如果消息由发送端口 (在基于内容的路由) 情况下,则发送端口必须为来自 Oracle Database 适配器接收端口的消息提供按序送达集。

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

Port 属性 订阅服务器已取消登记状态 订阅服务器已登记但已停止状态
未设置"失败时挂起请求消息"属性 -路由故障报表作为挂起的 (不可恢复的消息生成)

-实际消息未挂起

-如果事务被中止,则不会执行 Post 轮询查询。 因此轮询重复并再次提取行。

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

-实际消息将置于挂起的 (可恢复) 队列中。

-当订阅端口或业务流程启动时,消息将自动恢复。 如果在订阅服务器上设置了按序送达,则会遵守。

-还可以手动恢复消息。
设置了"失败时挂起请求消息"属性 -路由故障报表作为挂起的 (不可恢复的消息生成)

-实际消息也处于挂起状态

-如果事务被中止,则不会执行 Post 轮询查询。 因此轮询重复并再次提取行。

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

-实际消息将置于挂起的 (可恢复) 队列中。

-当订阅端口或业务流程启动时,消息将自动恢复。 如果在订阅服务器上设置了按序送达,则会遵守。

-还可以手动恢复消息。

另请参阅

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