Повторное использование объекта IBM.WMQ.MQQueue - PullRequest
4 голосов
/ 09 декабря 2010

Мы используем .NET API для IBM WebSphere MQ.

Создание объекта MQQueueManager, безусловно, является дорогостоящей операцией, поэтому мы кешируем и повторно используем пул этих объектов.

В настоящее время для каждого запроса мы получаем доступ к требуемым очередям:

//obtain queueManager from pool
IBM.WMQ.MQQueue requestQ= queueManager.AccessQueue(requestQName, mqOptions);
IBM.WMQ.MQQueue responseQ= queueManager.AccessQueue(responseQName, mqOptions);

и закрываем их после завершения:

requestQ.Close();
responseQ.Close();

Это наилучшая практикатакже пул и повторное использование объектов MQQueue (в дополнение к администратору очередей)?AccessQueue () выглядит дешевой операцией на клиенте.

1 Ответ

0 голосов
/ 30 января 2011

Ответ зависит от вашей модели потоков и транзакций. Как правило, клиенты обмена сообщениями всегда должны использовать транзакционность, даже если это только однофазная фиксация. Причина в том, что существуют неоднозначности результатов, которые могут вызвать дублирование или потерю сообщений в противном случае. Я предоставил более подробное объяснение этого в другом ответе .

Проблема в том, что транзакции ограничены подключением. Когда вы делаете COMMIT, вы делаете это для всего соединения. Безопасное использование одного и того же соединения в нескольких потоках исключает использование транзакций и, таким образом, приводит к тому, что приложение теряет или дублирует сообщения. Поскольку дескрипторы очереди действительны только в контексте определенного соединения, они наследуются от вашей модели потоков и пула соединений.

Наиболее распространенная модель для приложения поставщика услуг - поддерживать соединение для каждого потока во входной очереди и динамически открывать / помещать / закрывать выходную очередь. Например, в одной единице работы ...

  1. Прочитать следующее сообщение запроса
  2. Используйте информацию ответа для получения пункта назначения
  3. Открыть очередь ответа
  4. Поставь ответ
  5. Commit
  6. Уничтожить целевой объект ответа и, таким образом, закрыть очередь ответа

В этом случае соединения не перестраиваются постоянно, а входная очередь никогда не закрывается. Однако требуется, чтобы каждый поток поддерживал выделенное соединение.

...