适用于 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 | 确保该值设置为 轮询。 | 民意调查 | 必填。 如果未显式设置,则默认值将适用。 | 
| 数据可用性声明 | 指定要执行的 SELECT 语句,以检查特定表中是否有任何数据可供查询。 指定的语句必须返回由行和列组成的结果集。 结果集的第一个单元格中的值指示适配器是否执行 为 PollingStatement 绑定属性指定的值。 如果结果的第一个单元格包含正数值,适配器将执行轮询指令。 例如,此绑定属性的有效语句将为: Select * from <table_name>注意: 不能为此绑定属性指定存储过程。 此外,此语句不得修改基础 Oracle 数据库。 | 从DUAL选择1 | 必填。 如果未显式设置,则默认值将适用,这意味着适配器必须继续轮询,无论要轮询的表是否具有数据。 | 
| PollingAction | 指定轮询操作的动作。 可以使用适配器服务外接程序为操作生成的元数据,确定特定操作的轮询动作。 | Null | (可选)用于使用 SELECT 语句对表和视图进行操作的查询。 | 
| PollingInterval | 设置为希望适配器查询 Oracle 数据库的间隔(以秒为单位)。 此属性指定轮询间隔和轮询事务超时。该值应大于在 Oracle 数据库上执行查询和轮询后语句(如果指定了查询)所需的时间,以及客户端处理查询数据并返回轮询响应消息所需的时间。 | 500 | 必填。 如果未显式设置,则默认值将适用。 | 
| PollingStatement | 指定以下任一项: - 应针对 Oracle 数据库执行的 SQL SELECT 语句。 此语句应包含 FOR UPDATE 子句。 有关 FOR UPDATE 子句的信息,请参阅本主题后面的 轮询语句中指定 FOR UPDATE 子句 。 - 请求轮询包中存储过程、函数或过程的消息。 | Null | 必填。 将 PollingStatement 设置为非空值可启用轮询。 | 
| PollWhileDataFound | 指定如果正在轮询的表中的数据可用,Oracle 数据库适配器是否忽略轮询间隔并持续轮询 Oracle 数据库。 如果表中没有可用数据,适配器将还原为按指定的轮询间隔执行 SQL 语句 | 假 | 必填。 如果未显式设置,则默认值将适用。 | 
| 投票后声明 | 设置为可选的 PL/SQL 代码块,该块由适配器在执行查询后执行,但在查询数据返回到客户端之前。 | Null | 可选。 如果未指定任何值,则不会执行 post poll 语句。 | 
注释
如果使用 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 关键字以及 FOR UPDATE 关键字。 如果轮询查询尝试选择的行存在锁,这将导致适配器中的轮询查询立即返回。 Oracle 通常会在此类情况下引发异常。 同样,适配器客户端可以使用 PollingInterval 绑定属性指定适配器客户端必须重试轮询数据的时间间隔。
使用 NOWAIT 选项的轮询查询的示例为:
SELECT * from EMP WHERE FLAG = 'Y' FOR UPDATE NOWAIT  
在轮询语句中添加 SKIP LOCKED 子句
在某些情况下,可能会因为多个线程同时访问正在轮询的表,导致轮询查询中指定的 WHERE 子句的结果集中的某些行被锁定。 例如,轮询查询从表中返回 6 行;由于其他一些事务,这 6 行中有 4 行已被锁定。 在这种情况下,你可能想要指定 SKIP LOCKED 关键字以及 FOR UPDATE 关键字,该关键字指示数据库尝试锁定 WHERE 子句指定的行,并跳过发现已锁定的任何行。 WHERE 子句中未加锁的行在事务期间会被锁定,而后续语句可以对其进行任何所需的更新,以使这些行不会再次被轮询。 这可确保你在解锁 WHERE 子句指定的所有行之前就能够接收到轮询消息,而不必等待。
在多台计算机上有客户端适配器同时轮询数据库中的同一个表的情况下,SKIP LOCKED 关键字非常有用。 可以通过配置轮询操作在适配器客户端之间实现负载均衡。这样可以为在该时间点解锁的 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 数据库中接收基于轮询的数据更改消息