首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >BizTalk -从DB接收端口读取两次

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

Stack Overflow用户
提问于 2010-01-29 22:33:18
回答 1查看 4.7K关注 0票数 3

我的接收端口是sqlBinding和输入轮询。它调用一个SP来获取一个记录,并根据过滤器条件启动相应的编排。BizTalk组由2台服务器组成,因此有2台ReceiveHostInstances。如果两个主机实例都在运行-at,那么同一请求将被读取两次--在接收端造成重复。但是,为什么读取它的端口不止一次是相同的记录呢?读取记录并更新记录的proc,这样它就不会再被调用了。

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

我在一个主机上尝试了相同的请求(10个请求)(就像在Dev中一样),接收只显示了10个。有什么线索吗?

EN

回答 1

Stack Overflow用户

发布于 2010-01-30 01:28:55

快速的答案是,您有两个选项来解决这个问题:

  1. 修正您的存储过程,以便在并发情况下行为正确。
  2. 将SQL轮询接收处理程序放置在群集BizTalk主机中。

下面是对正在发生的事情的解释,并在下面给出解决这个问题的实现细节:

解释

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

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

这通常不是一个问题-大多数接收适配器可以管理这一点,并给您的行为,您会期待。例如,文件适配器在读取文件时对它们设置一个锁,从而防止双重读取。

当轮询SQL接收位置命中存储过程时,这正是问题所在的主要位置。在这种情况下,BizTalk除了信任SQL过程给出正确的结果之外别无选择。

看不见你的程序是很难分辨的,但是你查询记录的方式并不能保证唯一的读取。

也许你有这样的东西:

代码语言:javascript
复制
Select * From Record 
Where Status = 'Unread'

Update Record 
Set Status = 'Read'
Where Status = 'Unread'

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

实现解决方案

固定程序

这个过程的一个简单的修复方法是首先用唯一的id进行更新:

代码语言:javascript
复制
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服务器管理控制台中,当创建新主机时,可以指定该主机是群集的。有关此操作的详细信息载于此肯特·韦尔( Kent Weare )中。

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

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

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

票数 8
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/2165668

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档