У меня есть требование, по которому я буду получать партию записей. Я должен разобрать и вставить данные в БД, которую я закончил. Но я не хочу, чтобы из конвейера выходило какое-либо сообщение, кроме последнего настроенного сообщения.
Я расширил FFDasm
и позвонил Disassembler()
, затем у нас есть GetNext()
, который возвращает каждое дебатированное сообщение, и они терпят неудачу из-за наличия подписчиков. Я не хочу ничего отправлять с GetNext()
до последнего сообщения.
Пожалуйста, помогите, если кто-то уже выполнил это требование. Спасибо!
Отображение соответствующего кода в вопросе поможет людям ответить на него.
Рекомендуемый подход - публиковать сообщения после этапа дизассемблирования в db окна сообщений BizTalk и использовать адаптер db для вставки в базу данных. Публикация сообщений в окне сообщений и использование адаптера предоставят вам больше возможностей по дизайну / производительности и отделят вашу вставку БД от логики приема. Также в будущем, если вы захотите повторно использовать то же сообщение для чего-то еще, вы сможете это сделать.
Даже тогда, по какой-либо причине, если вам нужно вставить из компонента конвейера, выполните следующие действия:
Обратите внимание, что метод GetNext () интерфейса IDisassembler не вызывается, пока метод Disassemble () не будет завершен. Исходя из этого, вы можете использовать следующий подход, предполагая, что вы инкапсулировали FFDASM в свой собственный компонент:
Вставьте все дизассемблированные сообщения в сам метод дизассемблирования и поместите в очередь только последнее сообщение в переменную класса Queue. В сообщении GetNext () верните сообщение Dequeued, когда очередь пуста, верните null. Вы можете оптимизировать вставку БД, вставляя несколько строк за раз и сохраняя их партиями в зависимости от объема. Обратите внимание, что этот подход может вызвать проблемы с производительностью в зависимости от размера файла и количества строк, вставляемых в базу данных.
Привет, Викас, на данный момент я вызываю DBInsert SP из GetNext (), поскольку я получаю каждую отдельную запись в GetNext (). Мой объем огромен, около 25К записей плоских файлов, которые необходимо сначала сохранить в БД. В последнем сообщении я запускаю orch для опроса каждой записи и преобразования в запрос SOAP.
Привет, Викас, на данный момент я вызываю DBInsert SP из GetNext (), поскольку я получаю каждую отдельную запись в GetNext (). Мой объем огромен, около 25К записей плоских файлов, которые необходимо сначала сохранить в БД. В последнем сообщении я запускаю orch для опроса каждой записи и преобразования в запрос SOAP. Вызов SP в Disassembler () сильно снизит производительность. Вот почему я использую GetNext (), но для каждого GetNext () отправляется фиктивное сообщение, которого я хочу избежать. Есть какой-либо способ сделать это?
Вам лучше использовать другой подход, 25k - это не большой объем. Вы можете позволить этим сообщениям публиковаться в ящике сообщений, а оттуда вы можете отправить их в MSMQ. И тогда ты можешь делать с ними все, что хочешь. MSMQ можно использовать на любом сервере BizTalk, который у вас есть, и он является частью Windows. Вы можете использовать адаптер MSMQ для отправки или получения сообщений из очереди и обработки их для перехода в обе БД, а также для создания запроса SOAP.
Нет Викас, это не принято. Это предоставленная Архитектура, и я должен ей следовать. Итак, нет способа остановить GetNext () для публикации пустого сообщения в MsgBox?
I am calling DBInsert SP from GetNext()
Ох ... так ... извините, но вы делаете это неправильно и на самом деле создаете кучу проблем, делая это. :(
Это очень простой сценарий, который можно использовать с BizTalk Server. Все что тебе нужно это:
Чтобы быть на 100% ясным, здесь нет практических проблем с производительностью. Догадавшись о «производительности», вы на самом деле создали проблему, которую собирались решить, и создали кучу проблем поддержки, на которые позже, извините. :( Нет причин не использовать оркестровку.
Как уже отмечалось, 25 тысяч записей - это не так уж и много. Убедитесь, что расположение приема и оркестровка находятся на разных хостах.
Привет, Джонс! Мое требование таково, что я должен вызывать SP из конвейера, чтобы избежать потери данных. 1. Загрузите данные в БД 2. Создайте запрос мыла для каждой записи. 3. Получите ответ SOAP. 4. Сгруппируйте все ответы и отправьте во внешнюю систему как FF.
Ладно ... даже хуже. Извините, но вы создаете потенциально катастрофические пробелы, делая это. Это означает, что вы создаете гораздо большую вероятность потери данных путем вызова SP в конвейере вместо использования всех функций надежности BizTalk. Использование BizTalk в том виде, в каком я его описываю, полностью надежно и, откровенно говоря, намного надежнее, чем шаблон, который вы уже реализовали.
Все, что вы описываете, должно быть выполнено с помощью Orchestration и DB Adapters, в которых вы встроили повторные попытки, обработку ошибок и т. д. В противном случае вам придется в основном переписывать все это самостоятельно.
У орхидейного подхода есть проблема. 1. Вам нужен один orch только для вызова SP с повторением и обработкой ошибок. 2. вам нужен еще один орч для опроса БД, создания ответа на запрос. Я хочу удалить 1-й орч, вызвав SP в БД, и не хочу, чтобы это дебатированное сообщение публиковалось в msgBox.
Но это не «проблемы». Их просто нет. Вы можете сделать все это в одной оркестровке, если хотите. Хотя, наверное, я бы использовал два, может, три звонка подряд. В этом нет ничего плохого, ничего. Фактически, это правильный путь.
Извини, Джон, мне нужно выполнить вставку БД из конвейера и оркестрации только для создания запроса SOAP, получения ответа и т. д.
Простите, но почему? Что вы планируете реализовать для отработки отказа, повторных попыток, ведения журнала, обработки ошибок, телеметрии и т. д., От которых вы отказываетесь? Какие диагностические инструменты вы будете писать? Вы определили все случаи исключения и планы для каждого?
Кто бы ни заставлял вас это делать, опасно ошибается, и я гарантирую, что это вызовет проблемы для вас и вашего приложения. Вы должны дать своему руководству 100% понять, что это очень плохой и рискованный проект, потому что в противном случае он станет вашей проблемой.
Если вы хотите отправить только одно сообщение в GetNext, вам нужно вызвать метод Disassemble для базового Disassemble и получить все сообщения (вы можете поставить эти сообщения в очередь для управления ими в GetNext) как:
public new void Disassemble(IPipelineContext pContext, IBaseMessage pInMsg)
{
try
{
base.Disassemble(pContext, pInMsg);
IBaseMessage message = base.GetNext(pContext);
while (message != null)
{
// Only store one message
if (this.messagesCount == 0)
{
// _message is a Queue<IBaseMessage>
this._messages.Enqueue(message);
this.messagesCount++;
}
message = base.GetNext(pContext);
}
}
catch (Exception ex)
{
// Manage errors
}
Затем в методе GetNext у вас есть очередь, и вы можете вернуть все, что захотите:
public new IBaseMessage GetNext(IPipelineContext pContext)
{
return _messages.Dequeue();
}
Похоже, это решение. Позвольте мне попробовать, я вернусь к вам. Спасибо!
МИСТЕР. felixmondelo, Мое Вам искреннее спасибо. Это сработало потрясающе, и мы также добились рекордной производительности, вставив 25К данных в таблицу менее чем за минуту. Раньше это занимало около 7 минут. Это просто великолепно. Ваше решение сделало это возможным. БОЛЬШОГО ПРИВЕТСТВИЯ вам !!!
Для будущих читателей: НЕ ДЕЛАЙТЕ ЭТОГО. Это очень рискованный и хрупкий шаблон, который лишает многих преимуществ использования BizTalk. Есть несколько более эффективных способов добиться этого, даже если производительность менее 1 мин.
Извините, если вы вставляете в базу данных, как вы не обрабатываете сами пакетные сообщения?