让 JmsListenerContainerFactory 中的两个消费者顺序处理消息

问题描述 投票:0回答:1

我有一个类,它使用以下参数实现

JmsListenerContainerFactory

factory.setSessionTransacted(true);
factory.setConcurrency("1");
factory.setAutoStartup(true);

还有另一个

AtomikosConnectionFactoryBean
类型的类,具有以下参数:

atomikosfactory.setMaxPoolSize(2);

我还有两个队列,每个队列都由一个消费者处理:

@JmsListener(containerFactory = "jmsListenerContainerFactory", destination = "${queue-one}")
@Transactional
public <T> void handleOne(final Message<T> message)
{
   final var payload = message.getPayload();
   final var handler = getHandler(payload.getClass(););
   handler.handleOne(payload);
}

@JmsListener(containerFactory = "jmsListenerContainerFactory", destination = "${queue-two}")
@Transactional
public <T> void handleTwo(final Message<T> message)
{
   final var payload = message.getPayload();
   final var handler = getHandler(payload.getClass(););
   handler.handleTwo(payload);
}

不幸的是,两个处理程序都需要访问数据库中的相同条目。目前,这会导致意外行为,因为两者都试图同时访问它。我正在寻找一种方法来确保它们按顺序运行而不是同时运行。

我试图让我的

handleOne
handleTwo
方法调用标记为
@Synchronized
的相同方法,以确保它们不会同时运行。这是有效的,因为其中一个事务在尝试访问资源时会回滚,但那时某些操作已经执行,无法回滚。当线程在资源释放后尝试再次运行时,这会导致稍后出现错误。

java jms spring-jms
1个回答
0
投票

最终的解决方案是我可以使用以下参数设置将

ThreadPoolTaskExecuter
的对象传递给
JmsListenerContainerFactory

executor.setCorePoolSize(1);
executor.setMaxPoolSize(1);
executor.setQueueCapacity(100);
executor.initialize();

这具有所需的行为。

© www.soinside.com 2019 - 2024. All rights reserved.