Быстрый ответ: у вас есть два варианта решения этой проблемы:
- Исправьте хранимую процедуру, чтобы она правильно работала в параллельных ситуациях.
- Поместите обработчик получения SQL-запроса в кластерный хост BizTalk.
Ниже приводится объяснение того, что происходит, и ниже я даю подробную информацию о реализации, чтобы решить эту проблему:
Объяснение
Это связано с тем, что BizTalk получает местоположения при работе на нескольких экземплярах хоста (то есть обработчик получения для адаптера, указанного в местоположении получения, работает на хосте с несколькими экземплярами хоста).
В этой ситуации оба экземпляров хоста будут запускать свой обработчик получения.
Обычно это не проблема - большинство приемных адаптеров могут управлять этим и давать вам поведение, которое вы ожидаете. Например, файловый адаптер блокирует файлы во время их чтения, предотвращая двойное чтение.
Основное место, где возникает эта проблема, - именно то, что вы видите - когда местоположение приема SQL-запроса попадает в хранимую процедуру. В этом случае BizTalk не имеет другого выбора, кроме как доверять процедуре SQL для получения правильных результатов.
Трудно сказать, не видя вашей процедуры, но то, как вы запрашиваете свои записи, не гарантирует уникальное чтение.
Возможно, у вас есть что-то вроде:
Select * From Record
Where Status = 'Unread'
Update Record
Set Status = 'Read'
Where Status = 'Unread'
Вышеприведенная процедура может выдать дубликаты записей, потому что между выбором и обновлением другой вызов выбора может проникнуть и выбрать записи, которые еще не были обновлены.
Реализация решения
Исправление процедуры
Одним из простых исправлений процедуры является сначала обновление с уникальным идентификатором:
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 при создании нового хоста можно указать, что этот хост кластеризован . Подробная информация о том, как это сделать, содержится в этом сообщении Кента Уэйра .
По сути, вы создаете хост как обычно, с экземплярами хоста на каждом сервере, затем кликаете правой кнопкой мыши по хосту и выбираете кластер.
Затем вы создаете обработчик получения SQL для опроса, который работает на этом хосте, и используете этот обработчик в вашем месте получения.
Кластерный хост BizTalk гарантирует, что все элементы, являющиеся членами этого хоста, будут одновременно работать на одном и только одном экземпляре хоста. Это будет включать ваше местоположение получения SQL, поэтому у вас не будет никаких шансов на гонку при вызове вашей процедуры.