Это звучит как проблема с синхронизацией. Если бы QMgr выдавал COMMIT, когда сообщение помещалось в очередь внутри единицы работы, это затронуло бы все сообщения, находящиеся в точке синхронизации внутри этого потока. Это может вызвать серьезные проблемы, если приложение выполнило несколько вызовов PUT или GET до появления сообщения о заражении. Вместо того, чтобы выдавать COMMIT
вне контроля программы, QMgr просто оставляет сообщение в очереди возврата внутри единицы работы и ждет, пока программа выдаст COMMIT
. Это может привести к неожиданному поведению, например, к тому, что вы видите, когда сообщение возвращается во входную очередь.
Если другое сообщение находится в очереди за «плохим» и успешно обрабатывается той же нитью , все работает отлично. Приложение выдает COMMIT
для нового сообщения, и это также влияет на подозрительное сообщение в очереди возврата. Однако если поток должен был выйти нечистым образом (без явного отключения или COMMIT
), то транзакция откатывается и подозрительное сообщение возвращается во входную очередь.
Обычный способ справиться с этим состоит в том, что следующее правильное сообщение (или пакет сообщений, если транзакции пакетируются) во входной очереди будет вызывать COMMIT. Однако в некоторых случаях, когда поток-владелец не получает новую работу (возможно, он выполнял GET
по идентификатору корреляции), нет ничего, что могло бы пропустить плохое сообщение. В этих случаях важно убедиться, что приложение выдает COMMIT
перед завершением. Один из способов сделать это - написать код для выполнения GET
на CORRELID
с интервалом ожидания. Если интервал ожидания истекает, приложение получит код возврата 2033, а затем выдаст COMMIT
перед закрытием потока. Если ответное сообщение законно опаздывает по какой-либо причине, COMMIT
не будет иметь никакого эффекта. Но если сообщение прибыло и было возвращено и помещено в очередь, COMMIT
заставит его остаться в очереди возврата.
Один из способов точно понять, что происходит, - запустить трассировку в рассматриваемой очереди. Вы можете использовать встроенную функцию трассировки - strmqtrc, которая имеет несколько опций в V7 , чем версия V6 . Однако, если вы хотите очень мелкозернистое управление, вы можете использовать выход трассировки в SupportPac MA0W . С MA0W вы можете точно видеть, какие вызовы API выполняются программой и те, которые выполняются от ее имени.
[EDIT] Обновление ответа с некоторой информацией из PMR:
Следующее из Информационного центра WMQ V7:
MessageConsumers являются однопоточными ниже уровня сеанса, и
любая пересылка ядовитых сообщений
происходит в пределах текущей единицы
Работа. Это не влияет на
работа приложения, однако
когда ядовитые сообщения поставлены в очередь
по сделке или
Client_acknowledge Session,
само по себе действий не будет
совершено до текущей единицы
работа совершается по заявке
код или, при необходимости,
код контейнера приложения. "
Следовательно, если для клиента важно иметь отравляющие сообщения
совершено сразу после того, как они
отступили, рекомендуется, чтобы они
либо использовать приложение
Услуги сервера
(ConnectionConsumer), который может зафиксировать
сообщение немедленно или
еще один механизм перемещения яда
сообщения из очереди.
Вот ссылка на эту информацию в V6 и V7 Информационных центрах. Поскольку вы используете клиент V6, вы можете обратиться к инфоцентру V6. Обратите внимание, что в клиенте V6 в Инфоцентре ASF нет упоминания о возможности немедленной фиксации вредоносного сообщения, даже при использовании ConnectionConsumer . То, как я это прочитал, означает, что вам, вероятно, потребуется перейти на клиент V7, чтобы получить поведение, которое вы ищете. Будет интересно посмотреть, даст ли PMR аналогичную рекомендацию.