Spring AMQP/RabbitMQ 和 Hibernate 事务管理器

5
我有一个使用Hibernate和PostgreSQL的Spring应用程序。它还使用Spring AMQP(RabbitMQ)。
我正在使用如下配置的Hibernate事务管理器:
<bean id="transactionManager"
    class="org.springframework.orm.hibernate3.HibernateTransactionManager"
    p:sessionFactory-ref="sessionFactory" p:dataSource-ref="dataSource" />

我正在使用SimpleMessageListenerContainer作为异步消息接收器,配置如下:
@Resource(name="transactionManager")
private PlatformTransactionManager txManager;

@Autowired
private MyListener messageListener;

@Bean
public SimpleMessageListenerContainer mySMLC()
{
    final SimpleMessageListenerContainer container = new SimpleMessageListenerContainer();
    container.setConnectionFactory(rabbitConnectionFactory);
    container.setQueueNames("myQueue");

    final MessageListenerAdapter adapter = new MessageListenerAdapter(messageListener);
    adapter.setMessageConverter(converter);
    container.setMessageListener(adapter);
    container.setChannelTransacted(true);
    container.setTransactionManager(txManager);
    return container;
}

基本上,我已经指定了消息接收需要是事务性的。消息监听器调用一个可以使用带有 @Transactional 注释的方法并可能在数据库上执行 CRUD 操作的服务。

我的问题是,在 SimpleMessageListenerContainer 级别上使用 HibernateTransactionManager 来管理事务是否会有问题?在使用 DB 事务管理器包装从 RabbitMQ 接收消息时是否会出现任何问题?

我不期望 XA。我只想确保如果服务对数据库的任何操作失败,消息不会被确认给 RabbitMQ 代理。

1个回答

1
根据Spring源码,MessageListenerContainer的transactionManager属性的主要目的是在调用侦听器之前在接收到消息时启动事务,并在侦听器返回或引发异常后提交或回滚事务。因此,没有必要将侦听器方法设置为@Transactional,因为事务将在调用侦听器方法之前已经启动。
如果侦听器中出现错误,将抛出异常,DB事务将回滚,并且不会向消息代理发送确认(JMS事务回滚)。但是,如果没有XA,则可能存在重复消息。例如,在DB事务成功提交后,与消息代理的连接被重置,确认无法发送到代理。重新连接后,代理可能会传递重复的消息。如果您可以接受这一点,则无需处理XA。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接