2012-06-28 16 views
5

私は、HibernateとPostgreSQLを使用するSpringアプリケーションを持っています。 Spring AMQP(RabbitMQ)も使用します。Spring AMQP/RabbitMQとHibernate Transaction Mananger

私は次のように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で注釈が付けられたメソッドを持つことができ、DB上でCRUD操作を実行できるサービスを呼び出します。

私の質問は、HibernateTransactionManagerを使用してSimpleMessageListenerContainerレベルでトランザクションを管理する際に問題がありますか? RabbitMQからのメッセージの受信をラップするのにDBトランザクションマネージャを使用する際に問題はありますか?

私はここにXAを期待していません。サービスでDB上の操作が失敗した場合、メッセージはRabbitMQブローカーにアクセスされないようにしたいだけです。

答えて

1

MessageListenerContainerのtransactionManagerプロパティの主な目的は、リスナコールの前に受信したメッセージに対してトランザクションを開始し、リスナが例外を返すか、またはスローした後にトランザクションをコミットまたはロールバックすることです。リスナーメソッドが呼び出される前にトランザクションが既に開始されているので、リスナーメソッド@Transactionalを作成する必要はありません。

リスナーにエラーが発生した場合、例外がスローされ、DBトランザクションがロールバックされ、メッセージブローカーにackが送信されません(jmsトランザクションのロールバック)。しかし、XAがなければ、メッセージが重複する可能性があります。たとえば、DBトランザクションが正常にコミットされた後、メッセージブローカへの接続がリセットされ、ackをブローカに送信できませんでした。再接続後、ブローカは重複メッセージを配信できます。これを認めれば、XAに対処する必要はありません。

関連する問題