BizTalk WCF-OracleDB(后)轮询(可用)语句

时间:2019-07-02 14:20:50

标签: wcf oracle11g biztalk

对于使用WCF-OracleDB适配器在事务中进行轮询,我有一个普遍的问题,以确保被轮询的一(或多个)行也被更新为仅轮询一次。

在WCF-SQL中,我通常使用轮询(可用)语句。在PollingAvailableStatement中,我使用一个简单的COUNT(*)查询。在PollingStatement中,我通常查询下一行并在本地存储其ID。然后,我既查询数据又用状态更新行,以确保被轮询的行不再被轮询。而且,如果出现问题,则AmbientTransaction会将其回滚。

如何使用PostPollingStatement通过WCF-OracleDB-adapter实现相同的目的?我想念的是对我轮询的行的“引用”,以确保只有正确的行才能获得更新状态。

我当然尝试用Google搜索,但是每个人似乎都避免了这一要求...?

1 个答案:

答案 0 :(得分:0)

我无法在Oracle中找到任何功能组合来使用与SQL Server相同的解决方案,该解决方案具有更新轮询状态和返回数据的过程。因此,必须有另一种解决方案来针对Oracle数据库进行安全轮询。

Oracle有两种事务隔离级别模式,您需要使用 Serializable 才能使轮询正常工作。我认为这就像您进入序列化模式时所获得的数据库的“快照”。如果使用ReadCommitted,您将不受其他用户所做更改的影响。提交时,其他用户将看到您的更改,而您也会看到他们的更改。为了避免其他用户在可序列化模式下进行干扰,请确保使用 FOR UPDATE 锁定行。当您(或BizTalk)提交更改时,它将被释放。

底线,在可序列化模式下,相同的查询将始终返回相同的结果(如果您自己未更改的话)。这样,您就可以只更新以前轮询的行,即我的问题中缺少的“引用”。

此外,必须使用 UseAmbientTransaction 来确保BizTalk在出现问题时能够成功回滚事务。某些人建议不要使用PRAGMA AUTONOMOUS_TRANSACTION,因为它是子事务,BizTalk启动的事务无法回滚。

  

注意: EnableBizTalkCompatibilityMode 也应设置为True,但是我有   找不到原因或作用的任何解释。

因此,使用上述设置配置,WCF-OracleDB适配器将在执行PollingStatement之前自动进入可序列化模式,您将能够使用与PollingStatement相同的查询来接收数据并更新轮询状态,并且如果PostPollingStatement为成功。否则,AmbientTransaction将确保您的更改未提交。

并且,配置轮询语句:

PollingAvailableStatement

SELECT COUNT(*) FROM <Table> WHERE POLLED = 0

投票声明

SELECT * FROM <Table> WHERE POLLED = 0 ORDER BY Date ASC FOR UPDATE

PostPollingStatement

 UPDATE <Table> SET POLLED = 1 WHERE POLLED = 0

在现实世界中,您可能还必须考虑批处理(在Oracle中使用ROWNUM),这意味着您需要构建类似于以下内容的查询:

SELECT * 
FROM <Table> 
WHERE PK IN 
(
    SELECT PK
    FROM (
        SELECT *
        FROM <Table>
        WHERE POLLED = 0
        ORDER BY PK ASC
     )
     WHERE ROWNUM <=10
)
FOR UPDATE;

和:

UPDATE <Table> 
SET POLLED = 1
WHERE PK IN 
(
    SELECT PK
    FROM (
        SELECT *
        FROM <Table>
        WHERE POLLED = 0
        ORDER BY PK ASC
     )
     WHERE ROWNUM <=10
)

这里的要点是必须先执行WHERE和ORDER BY,然后ROWNUM才基于该子查询(或视图)。