2012-06-28 27 views
5

Tengo una aplicación Spring que usa Hibernate y PostgreSQL. También utiliza Spring AMQP (RabbitMQ).Spring AMQP/RabbitMQ y Hibernate Transaction Mananger

estoy usando el gestor de Transaction de Hibernate configurado de la siguiente manera:

<bean id="transactionManager" 
    class="org.springframework.orm.hibernate3.HibernateTransactionManager" 
    p:sessionFactory-ref="sessionFactory" p:dataSource-ref="dataSource" /> 

estoy usando el SimpleMessageListenerContainer para la recepción de mensajes asíncronos configurado como:

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

Así que básicamente he especificado que la recepción de mensajes debe ser transaccional. El oyente de mensajes llama a un servicio que puede tener métodos anotados con @Transactional y posiblemente realizar operaciones CRUD en el DB.

Mi pregunta es, ¿hay algún problema con el HibernateTransactionManager para administrar la transacción en el nivel SimpleMessageListenerContainer? ¿Habrá algún problema al usar un administrador de transacciones DB para envolver la recepción de mensajes de RabbitMQ?

No estoy esperando XA aquí. Solo quiero asegurarme de que si el servicio falla alguna de las operaciones en la base de datos, el mensaje no se envía al intermediario RabbitMQ.

Respuesta

1

Según las fuentes de Spring, el objetivo principal de la propiedad transactionManager de MessageListenerContainer es iniciar la transacción en el mensaje recibido antes de la llamada de escucha, y confirmar o revertir la transacción después de que el detector devuelva o genere una excepción. Por lo tanto, no es necesario crear métodos de escucha @Transactional ya que la transacción ya se iniciará antes de llamar al método de escucha.

En caso de error en el oyente, se lanzará una excepción, la transacción DB se retrotraerá y no se enviará ack al intermediario de mensajes (repliegue de la transacción jms). Pero sin XA, puede haber mensajes duplicados. Por ejemplo, después de que la transacción DB se haya confirmado correctamente, la conexión al restablecimiento del intermediario de mensajes y ack no pudieron enviarse al intermediario. Después de volver a conectarse, el intermediario podría entregar un mensaje duplicado. Si admite esto, no es necesario tratar con XA.

Cuestiones relacionadas