BizTalk - 从DB接收端口读取两次

时间:2010-01-29 22:33:19

标签: biztalk polling

我的接收端口是sqlBinding和键入轮询。它调用SP来获取记录,并根据过滤条件启动相应的业务流程。 BizTalk组由2台服务​​器组成;因此2 ReceiveHostInstances。如果两个主机实例都在运行 - 某些点,则相同的请求被读取两次 - 在接收器端导致重复。但是,为什么反应端口不止一次读取同一记录呢?读取更新记录并更新它的proc,以便它不会再次被删除。

我在提交10个请求时观察到了这种情况;接收端口读取11次,11个编排开始。

我尝试了同一个(10个请求)和一个主机(在我的Dev中),接收只显示10个。有线索吗?

1 个答案:

答案 0 :(得分:7)

快速回答是您有两​​种方法可以解决此问题:

  1. 修复存储过程,使其在并发情况下正常运行。
  2. 将SQL轮询接收处理程序放在集群BizTalk主机中。
  3. 下面是对正在发生的事情的解释,并在此基础上详细说明解决问题的实现:

    说明

    这是由于BizTalk在多个主机实例上运行时接收位置的方式(即,接收位置中指定的适配器的接收处理程序在具有多个主机实例的主机上运行)。

    在这种情况下,主机实例的两个都将运行其接收处理程序。

    这通常不是问题 - 大多数接收适配器都可以管理它并为您提供您期望的行为。例如,文件适配器在读取文件时会锁定文件,从而防止双重读取。

    这是一个问题的主要地方正是您所看到的 - 当轮询SQL接收位置正在命中存储过程时。在这种情况下,除了信任SQL过程以提供正确的结果之外,BizTalk没有其他选择。

    如果没有看到您的程序,很难分辨,但您查询记录的方式并不能保证独特的读取。

    也许你有类似的东西:

    Select * From Record 
    Where Status = 'Unread'
    
    Update Record 
    Set Status = 'Read'
    Where Status = 'Unread'
    

    上述过程可以提供重复记录,因为在select和更新之间,select的另一个调用能够潜入并选择尚未更新的记录。

    实施解决方案

    修复程序

    该程序的一个简单修复是首先使用唯一ID进行更新:

    Update Record 
    Set UpdateId = @@SPID, Status = 'Reading'
    Where Status = 'Unread'
    
    Select * From Record
    Where UpdateId = @@SPID
    And Status = 'Reading'
    
    Update Record
    Set Status = 'Read'
    Where UpdateId = @@SPID
    And Status = 'Reading'
    

    @@ SPID应该是唯一的,但如果证明不是,你可以使用newid()

    使用群集主机

    在创建新主机时,在BizTalk服务器管理控制台中,可以指定该主机是 clustered 。有关执行此操作的详细信息,请参阅此post by Kent Weare

    基本上,您可以正常创建主机,每台服务器上都有主机实例,然后右键单击主机并选择群集。

    然后,为在该主机下工作的轮询创建SQL接收处理程序,并在接收位置使用此处理程序。

    BizTalk集群主机确保作为该主机成员的所有项目一次只能在一个主机实例上运行。这将包括您的SQL接收位置,因此您在调用过程时不会有任何竞争条件。