BizTalk - 接收端口从数据库读取两次
我的接收端口是 sqlBinding 和类型轮询。它调用 SP 来获取记录,并根据过滤条件启动相应的编排。 BizTalk组由2台服务器组成;因此有 2 个 ReceiveHostInstances。如果两个主机实例都在运行 - 在某些时候相同的请求被读取两次 - 导致接收端出现重复。但是,为什么接收端口多次读取同一条记录呢?读取记录的过程会更新记录并更新它,以便它不会再次受到影响。
我在提交 10 个请求时观察到了这种情况;接收端口读取 11 次并启动 11 个编排。
我对一台主机(如在我的开发中)尝试了相同的操作(10 个请求),接收仅显示 10 个。有什么线索吗?
My receive port is of sqlBinding and typed polling. It invokes a SP to fetch a record and based on filter condition the corresponding orchestration kicks off. The BizTalk group consists of 2 servers; thus 2 ReceiveHostInstances. If both the host instances are running -at some point the same request is being read twice - causing a duplicate at the receivers end. But, why is the reeive port reading it the same record more than once? The proc which reads the updates the record and updates it so that it wont be fecthed again.
I observed this scenario while submitting 10 requests; receive port read 11 times and 11 orchestrations started.
I tried the same (10 request) with one host (as in my Dev), the receive is showing 10 only. Any clues?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
快速的答案是,您有两个选项可以解决此问题:
下面是对正在发生的事情的解释,并在其中提供了解决该问题的实现的详细信息:
解释
这是由于在多个主机实例上运行时 BizTalk 接收位置的工作方式(即,接收位置中指定的适配器正在具有多个主机实例的主机上运行)。
在这种情况下,两个主机实例都将运行其接收处理程序。
这通常不是问题 - 大多数接收适配器都可以管理此问题并为您提供您所期望的行为。例如,文件适配器在读取文件时对其进行锁定,以防止重复读取。
出现此问题的主要位置正是您所看到的 - 当轮询 SQL 接收位置正在命中存储过程时。在这种情况下,BizTalk 没有其他选择,只能相信 SQL 过程会给出正确的结果。
如果不查看您的过程,很难判断,但是您查询记录的方式并不能保证唯一的读取。
也许您有这样的情况:
上面的过程可能会给出重复的记录,因为在选择和更新之间,选择的另一个调用能够潜入并选择尚未更新的记录。
实施解决方案
修复过程 该
过程的一个简单修复是首先使用唯一的 id 进行更新:
@@SPID 应该是唯一的,但如果证明不是唯一的,您可以使用 newid()
使用群集主机
在 BizTalk 服务器管理中 创建新主机时,可以指定该主机是集群的。有关执行此操作的详细信息,请参阅 Kent Weare 的帖子。
本质上,您可以像往常一样创建一个主机,在每个服务器上都有主机实例,然后右键单击该主机并选择集群。
然后,您为在该主机下工作的轮询创建一个 SQL 接收处理程序,并在您的接收位置使用该处理程序。
BizTalk 群集主机可确保属于该主机成员的所有项目一次只能在一个主机实例上运行。这将包括您的 SQL 接收位置,因此您在调用过程时不会有任何竞争条件的机会。
The quick answer is that you have two options to fix this problem:
Below is an explanation of what is going on, and under that I give details of implementations to fix the issue:
Explanation
This is due to the way BizTalk receive locations work when running on multiple host instances (that is, that the receive handler for the adapter specified in the receive location is running on a host that has multiple host instances).
In this situation both of the host instances will run their receive handler.
This is usually not a problem - most of the receive adapters can manage this and give you the behaviour you would expect. For example, the file adapter places a lock on files while they are being read, preventing double reads.
The main place where this is a problem is exactly what you are seeing - when a polling SQL receive location is hitting a stored procedure. In this case BizTalk has no option other than to trust the SQL procedure to give the correct results.
It is hard to tell without seeing your procedure, but the way you are querying your records is not guaranteeing unique reads.
Perhaps you have something like:
The above procedure can give duplicate records because between the select and the update, another call of the select is able to sneak in and select the records that have not been updated yet.
Implementing a solution
Fixing the procedure
One simple fix to the procedure is to update with a unique id first:
@@SPID should be unique, but if it proves not to be you could use newid()
Using a clustered host
Within the BizTalk server admin console when creating a new host it is possible to specify that that host is clustered. Details on doing this are in this post by Kent Weare.
Essentially you create a host as normal, with host instances on each server, then right click the host and select cluster.
You then create a SQL receive handler for the polling that works under that host and use this handler in your receive location.
A BizTalk clustered host ensures that all items that are members of that host will run on one and only one host instance at a time. This will include your SQL receive location, so you will not have any chance of race conditions when calling your procedure.