Не удается получить JMS, поскольку отправленная транзакция не передана - PullRequest
0 голосов
/ 28 мая 2018

У меня есть два приложения Apple и Pear, которые используют вышеупомянутый класс для прослушивания настроенной очереди JMS в WildFly (10.1.0).Конфигурация Spring показана ниже.

<bean id="appleMessageListenerContainer"
    class="org.springframework.jms.listener.DefaultMessageListenerContainer"
    depends-on="transactionManager">
    <property name="connectionFactory" ref="connectionFactory" />
    <property name="destination" ref="outQueue" />
    <property name="destinationResolver" ref="jmsDestinationResolver" />
    <property name="messageListener" ref="AppleMessageListener" />
    <property name="messageSelector" value="ID='APPLE_ID'" />
    <property name="transactionManager" ref="transactionManager" />
</bean>

<bean id="pearMessageListenerContainer"
    class="org.springframework.jms.listener.DefaultMessageListenerContainer"
    depends-on="transactionManager">
    <property name="connectionFactory" ref="connectionFactory" />
    <property name="destination" ref="outQueue" />
    <property name="destinationResolver" ref="jmsDestinationResolver" />
    <property name="messageListener" ref="PearMessageListener" />
    <property name="messageSelector" value="ID='PEAR_ID'" />
    <property name="transactionManager" ref="transactionManager" />
</bean>

Ожидаемый процесс выглядит следующим образом: - Слушатель приложения Apple (AppleMessageListener) будет читать сообщение из очереди JMS outQueue.Сообщение обновляется, и AppleMessageListener записывает сообщение в «outQueue» с senderId, установленным в «PEAR_ID», так что PearMessageListener будет читать сообщение.AppleMessageListener будет ожидать ответа от приложения Pear на другое «inQueue» или тайм-аут

Extarct по следующей ссылке: -

https://www.ibm.com/support/knowledgecenter/en/SSFKSJ_7.5.0/com.ibm.mq.dev.doc/q032250_.htm

If an application sends a message within a transaction, the message 
is not delivered to its destination until the transaction is committed. 
This means that an application cannot send a message and receive a reply 
to the message within the same transaction.

Этоточно моя ситуация.Однако я не могу найти решение, которое я могу понять.

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

Спасибо за вашу помощь.

Пит

1 Ответ

0 голосов
/ 28 мая 2018

Вы можете использовать Исходящий шлюз JMS Spring Integration , который решает эту проблему.

EDIT

Вот приложение Spring Boot, использующее Spring Integration ;надеюсь, это говорит само за себя ...

@SpringBootApplication
public class So50572316Application {

    public static void main(String[] args) {
        SpringApplication.run(So50572316Application.class, args);
    }

    @Bean
    public ApplicationRunner runner(JmsTemplate template) {
        return args -> {
            MessagePostProcessor mpp = m -> {
                m.setStringProperty("ID", "APPLE_ID");
                return m;
            };
            template.convertAndSend("outQueue", "foo", mpp);
            template.convertAndSend("outQueue", "fail", mpp);
        };
    }

    @Bean
    public IntegrationFlow appleFlow(ConnectionFactory connectionFactory) {
        return IntegrationFlows.from(Jms.messageDrivenChannelAdapter(connectionFactory)
                .destination("outQueue")
                .configureListenerContainer(c -> c.messageSelector("ID='APPLE_ID'")))
            .handle("appleHandler", "handle")
            .handle(Jms.outboundGateway(new CachingConnectionFactory(connectionFactory))
                    .requestDestination("outQueue")
                    .headerMapper(headerMapper()))
            .handle("resultHandler", "handle")
            .get();
    }

    @Bean
    public AppleHandler appleHandler() {
        return new AppleHandler();
    }

    @Bean
    public ResultHandler resultHandler() {
        return new ResultHandler();
    }

    @Bean
    public IntegrationFlow pearFlow(ConnectionFactory connectionFactory) {
        return IntegrationFlows.from(Jms.inboundGateway(connectionFactory)
                .destination("outQueue")
                .configureListenerContainer(c -> c.messageSelector("ID='PEAR_ID'")))
            .handle("pearHandler", "handle")
            .get();
    }

    @Bean
    public PearHandler pearHandler() {
        return new PearHandler();
    }

    private JmsHeaderMapper headerMapper() {
        return new DefaultJmsHeaderMapper() {

            @Override
            public void fromHeaders(MessageHeaders headers, Message jmsMessage) {
                super.fromHeaders(headers, jmsMessage);
                try {
                    jmsMessage.setStringProperty("ID", "PEAR_ID");
                }
                catch (JMSException e) {
                    e.printStackTrace();
                }
            }

        };
    }

}

class AppleHandler {

    @ServiceActivator
    public String handle(String in) {
        System.out.println("Apple:" + in);
        return in.toUpperCase();
    }

}

class ResultHandler {

    @ServiceActivator
    public void handle(String result) {
        if ("FAILFAIL".equals(result)) {
            throw new RuntimeException("testRollback");
        }
        System.out.println("Result:" + result);
    }

}

class PearHandler {

    @ServiceActivator
    public String handle(String in) {
        System.out.println("Pear:" + in);
        return in + in;
    }

}

и

Apple:foo
Pear:FOO
Result:FOOFOO
Apple:fail
Pear:FAIL
2018-05-29 09:53:31.217  WARN 98472 --- [erContainer#0-1] o.s.j.l.DefaultMessageListenerContainer  : Execution of JMS message listener failed, and no ErrorHandler has been set.

org.springframework.messaging.MessageHandlingException: nested exception is java.lang.RuntimeException: testRollback
...
Apple:fail
Pear:FAIL
2018-05-29 09:53:32.224  WARN 98472 --- [erContainer#0-1] o.s.j.l.DefaultMessageListenerContainer  : Execution of JMS message listener failed, and no ErrorHandler has been set.

org.springframework.messaging.MessageHandlingException: nested exception is java.lang.RuntimeException: testRollback
...
...