Как отправить сообщение PCF в точке синхронизации?

У меня есть следующий код для получения информации об очереди, который выдает ошибку 2232 при выполнении в рамках транзакции:

Dim specificQMConnProperties As Hashtable = CType(queueManagerConnectionProperties.Clone(), Hashtable)
specificQMConnProperties.Add(MQC.HOST_NAME_PROPERTY, qmgrHostNameOrIP)
specificQMConnProperties.Add(MQC.PORT_PROPERTY, qmgrPort)
specificQMConnProperties.Add(MQC.CHANNEL_PROPERTY, qmgrChannel)
Dim qmgr As MQQueueManager = Nothing
Try
    qmgr = New MQQueueManager(qmgrName, specificQMConnProperties)
Catch ex As MQException
    Select Case ex.ReasonCode
        Case 2059, 2538
            ' qmgr or host not available
            Return nothing
        Case Else
            ' continue
    End Select
End Try

If qmgr IsNot Nothing Then
Try
    ' use PCF to get queue information.
    Dim agent As New PCFMessageAgent(qmgr)
    Dim request As New PCFMessage(CMQCFC.MQCMD_INQUIRE_Q)
    request.AddParameter(MQC.MQCA_Q_NAME, queueName)

    Dim responses As PCFMessage() = Nothing

    Try
        ' connected
        responses = agent.Send(request)
    Catch pcfex As PCFException
        LogException(pcfex, {queue}, "Exception checking queue availability via PCF. Assuming false")
        Return Nothing
    End Try

    If responses IsNot Nothing AndAlso responses.Any() Then
        LogDebug("Checking queue availability for " & queue.ToString() & " returned a PCF result.")
        return responses
    Else
        LogError("No result returned from PCF Message request on " & queue.ToString())
        Return Nothing
    End If
Catch ex As MQException
    LogException(ex, {queue})
    Return False
End Try
End If

Ошибка возникает в строке responses = agent.Send(request) следующим образом:

Код завершения: 2, код причины: 2232(2232=MQRC_UNIT_OF_WORK_NOT_STARTED) в IBM.WMQ.MQDestination.Put(сообщение MQMessage, MQPutMessageOptions pmo) в IBM.WMQ.PCF.PCFAgent.Send(команда Int32, параметры PCFParameter[]) в IBM .WMQ.PCF.PCFMessageAgent.Send(запрос PCFMessage, логическая проверка) в IBM.WMQ.PCF.PCFMessageAgent.Send(запрос PCFMessage) в MyMethod

К остальным параметрам подключения к транзакциям (например, для получения или отправки сообщения) добавлено Or MQC.MQGMO_SYNCPOINT, но я не вижу, как установить параметры подключения для сообщения PCF. Кто-нибудь может помочь?

Чтобы было ясно, мне все равно, будет ли он отправлен как часть транзакции, но поскольку Transactionscope открыт, я получаю эту ошибку.

--Редактировать--

Я добавил код подключения администратора очередей вверху.


person simonalexander2005    schedule 17.11.2015    source источник
comment
Есть ли причина, по которой вы хотите запускать команды PCF под транзакцией?   -  person Shashi    schedule 17.11.2015
comment
ну, это скорее часть потока команд, которые запускаются в рамках транзакции - результат команды PCF определяет, какой из нескольких вариантов имеет место - так что get, PCF, put here или put there; Например.   -  person simonalexander2005    schedule 17.11.2015
comment
Чтобы было ясно, меня не волнует, что он отправлен как часть транзакции, но поскольку Transactionscope открыт, я получаю эту ошибку.   -  person simonalexander2005    schedule 17.11.2015


Ответы (2)


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

PCFAgent может иметь собственное соединение. PCFAgent и PCFMessageAgent будут поддерживать собственное соединение с администратором очередей и, таким образом, избегают области транзакций в существующем соединении.

Я подозреваю, что qmgr в вашем коде является экземпляром MQQueueManager, хотя мы не можем видеть код в вашем вопросе, который его создал? Если вместо этого вы используете PCFMessageAgent для создания нового соединения с администратором очередей, у него будет свое собственное соединение и, следовательно, своя область транзакций.

См. class PCFMessageAgent для более подробной информации, но вкратце есть три конструктора, о которых вы должны знать, и я полагаю, что вы используете первый.

  • PCFMessageAgent(MQQueueManager qmanager)

    Инициализирует новый агент PCFMessageAgent с существующим подключением администратора очередей.

  • PCFMessageAgent(java.lang.String qmanager)

    Инициализирует новый агент PCFMessageAgent с подключением привязок к администратору очередей.

  • PCFMessageAgent(java.lang.String host, int port, java.lang.String channel)

    Инициализирует новый агент PCFMessageAgent с подключением клиента к администратору очередей.

Игнорирование области транзакций В качестве альтернативы вы можете поместить свой вызов PCFMessageAgent в новую область транзакций, используя параметр для подавления области транзакций среды, как подробно описано в другом вопросе StackOverflow: Игнорировать TransactionScope для определенного запроса

using (var scope = new TransactionScope(TransactionScopeOption.Suppress))
{
    /* Your PCFMessageAgent code in here */

}

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

person Morag Hughson    schedule 18.11.2015
comment
Спасибо за Ваш ответ. Во-первых, я использую .net(vb), а не Java, поэтому класс PCFMessageAgent, к сожалению, не имеет третьего конструктора (который мне нужен). Несмотря на то, что я создаю свое собственное соединение с администратором очередей для этого сообщения PCF, оно все равно не работает, потому что оно находится в TransactionScope - person simonalexander2005; 18.11.2015
comment
Можете ли вы подтвердить, что не используете это соединение администратора очередей ни для чего другого, кроме PCFMessageAgent? - person Morag Hughson; 20.11.2015
comment
Я могу это подтвердить. Метод создает подключение администратора очередей, как показано, затем сразу же использует его, и на этом метод заканчивается. - person simonalexander2005; 20.11.2015
comment
Предупреждение: я не пробовал это, и я недостаточно знаю о .NET, чтобы понять, сработает ли это для вас, но прочитайте это: stackoverflow.com/questions/18257122/ - person Morag Hughson; 21.11.2015
comment
эта ссылка работает отлично! Если вы добавите это к своему ответу, я приму это :) - person simonalexander2005; 23.11.2015
comment
Я добавил это в свой ответ, как вы предложили. Рад, что это сработало, так как я никогда не пробовал это! - person Morag Hughson; 25.11.2015

Это просто странно. Как, по-вашему, командный сервер диспетчера очередей может обработать вашу команду PCF, если она находится в UOW (единице работы)? Ваше сообщение PCF (помещенное в очередь командного сервера) невидимо, пока вы не сделаете фиксацию.

Я не знаю, почему вам нужно запрашивать очередь после получения, но единственный способ, которым это будет работать, - это вне UOW.

person Roger    schedule 17.11.2015