Spring JMS 编程侦听器端点和事务
Spring JMS programmatic listener endpoints and transactions
当我以编程方式注册 JMS 侦听器端点时,我不再拥有事务支持。
我将 TransactionAwareConnectionFactoryProxy 与 JDBC 数据源和 JMS 一起使用,它提供了像 JTA 那样的良好全局事务(1PC 全局 tx)。使用注释效果很好:
@JmsListener(containerFactory = "jmsQueueListenerContainerFactory", destination = "queue/exampleQueue")
@Transactional
public void onQueueMessage(Message message, Session session) {...}
但是对于编程端点注册,它不起作用。端点注册码:
@Override
public void configureJmsListeners(JmsListenerEndpointRegistrar registrar) {
registrar.setContainerFactory(jmsListenerContainerFactory());
SimpleJmsListenerEndpoint endpoint = new SimpleJmsListenerEndpoint();
endpoint.setId("Oelieboeliwieli");
endpoint.setDestination("queue/exampleQueue");
endpoint.setMessageListener(new Consumer());
registrar.registerEndpoint(endpoint);
}
听众只是:
@Transactional
public void onMessage(Message message) { ... }
这两种情况下的其他一切都是一样的。我的猜测是没有为处理全局事务的 onMessage()
方法生成代理。使用带注释的解决方案,我看到从 invokeWithinTransaction()
调用生成的代理。
知道如何以简单的方式做到这一点吗?
您正在手动创建 Consumer
,因此该对象根本不是托管 bean。应用程序上下文没有理由(实际上也没有办法)处理 class 并为其创建代理。
无论创建消息侦听器的是什么,都应该采用托管 bean。鉴于您提供的代码,很难理解为什么您需要进行程序化注册,但这是一个完全不同的话题。
当我以编程方式注册 JMS 侦听器端点时,我不再拥有事务支持。
我将 TransactionAwareConnectionFactoryProxy 与 JDBC 数据源和 JMS 一起使用,它提供了像 JTA 那样的良好全局事务(1PC 全局 tx)。使用注释效果很好:
@JmsListener(containerFactory = "jmsQueueListenerContainerFactory", destination = "queue/exampleQueue")
@Transactional
public void onQueueMessage(Message message, Session session) {...}
但是对于编程端点注册,它不起作用。端点注册码:
@Override
public void configureJmsListeners(JmsListenerEndpointRegistrar registrar) {
registrar.setContainerFactory(jmsListenerContainerFactory());
SimpleJmsListenerEndpoint endpoint = new SimpleJmsListenerEndpoint();
endpoint.setId("Oelieboeliwieli");
endpoint.setDestination("queue/exampleQueue");
endpoint.setMessageListener(new Consumer());
registrar.registerEndpoint(endpoint);
}
听众只是:
@Transactional
public void onMessage(Message message) { ... }
这两种情况下的其他一切都是一样的。我的猜测是没有为处理全局事务的 onMessage()
方法生成代理。使用带注释的解决方案,我看到从 invokeWithinTransaction()
调用生成的代理。
知道如何以简单的方式做到这一点吗?
您正在手动创建 Consumer
,因此该对象根本不是托管 bean。应用程序上下文没有理由(实际上也没有办法)处理 class 并为其创建代理。
无论创建消息侦听器的是什么,都应该采用托管 bean。鉴于您提供的代码,很难理解为什么您需要进行程序化注册,但这是一个完全不同的话题。