Spring AMQP/RabbitMQ和Hibernate事务管理器

Spring AMQP/RabbitMQ和Hibernate事务管理器,rabbitmq,spring-transactions,spring-amqp,spring-orm,Rabbitmq,Spring Transactions,Spring Amqp,Spring Orm,我有一个使用Hibernate和PostgreSQL的Spring应用程序。它还使用Spring AMQP(RabbitMQ) 我使用的Hibernate事务管理器配置如下: <bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager" p:sessionFactory-ref="sessionFactory" p:dataSource

我有一个使用Hibernate和PostgreSQL的Spring应用程序。它还使用Spring AMQP(RabbitMQ)

我使用的Hibernate事务管理器配置如下:

<bean id="transactionManager"
    class="org.springframework.orm.hibernate3.HibernateTransactionManager"
    p:sessionFactory-ref="sessionFactory" p:dataSource-ref="dataSource" />
因此,基本上我已经指定消息的接收需要是事务性的。消息侦听器调用一个服务,该服务可以使用@Transactional注释方法,并可能对DB执行CRUD操作

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


我在这里不期待XA。我只是想确保,如果服务在DB上的任何操作失败,消息不会得到RabbitMQ代理的确认。

根据Spring来源,MessageListenerContainer的transactionManager属性的主要目的是在侦听器调用之前对收到的消息启动事务,以及在侦听器返回或抛出异常后提交或回滚事务。因此,不需要将侦听器方法设置为@Transactional,因为在调用侦听器方法之前,事务已经启动。

如果侦听器中出现错误,将抛出异常,DB事务将回滚,并且不会向message broker发送ack(jms事务回滚)。但是如果没有XA,可能会有重复的消息。例如,在DB事务成功提交后,到message broker的连接重置,并且ack无法发送到代理。重新连接后,代理可以传递重复的消息。如果您承认这一点,就没有必要处理XA

@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;
}