由于未发送发送事务,JMS无法接收

时间:2018-05-28 19:10:25

标签: jms spring-jms

我有两个应用程序Apple和Pear使用上面的类来监听WildFly(10.1.0)中已配置的JMS队列。 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)将读取来自&#34; outQueue&#34; JMS队列。消息已更新,AppleMessageListener将消息写入&#34; outQueue&#34;将senderId设置为&#34; PEAR_ID&#34;,以便PearMessageListener将读取该消息。 AppleMessageListener将等待来自不同&#34; inQueue&#34;的Pear应用程序的响应。或超时

来自以下链接的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.

这正是我的情况。但是,我无法找到我能理解的解决方案。

我非常感谢有关我面临这个问题的建议。

感谢您的帮助。

皮特

2 个答案:

答案 0 :(得分:1)

您可以使用Spring Integration's JMS outbound gateway处理此问题。

修改

这是使用Spring Integration的Spring Boot应用程序;希望这是不言自明的......

@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
...

答案 1 :(得分:0)

我通过手动创建>>> a = np.arange(10) >>> a array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]) >>> np.where(a < 5, a, 10*a) array([ 0, 1, 2, 3, 4, 50, 60, 70, 80, 90]) 使用非事务JMS会话来解决。

JmsListenerContainerFactory
        factory.setTransactionManager(null);
        factory.setSessionTransacted(false);