Управление транзакциями JMS с помощью Spring

Я пытаюсь управлять транзакцией JMS с помощью Spring и HornetQ.
Вот код, который я написал:

public void receive() {
    TransactionStatus status = transactionManager.getTransaction(new DefaultTransactionDefinition());
    Message msg = jmsTemplate.receive(queue);
    boolean success = false;
    if (msg != null) {
            try {
               success = handleMessage(msg);
               if (success) { 
                   msg.acknowledge(); // session is still open within the transaction
               }
            } catch (JMSException e) {
                transactionManager.rollback(status);
            }
            if (success)
                transactionManager.commit(status);
            else
                transactionManager.rollback(status):
    }
}

Я выполняю синхронное чтение из очереди с тайм-аутом, равным 0, так как я не хочу блокировать чтение. Из-за этого я должен проверить, действительно ли что-то было получено.

Это выдержка из моего файла applicationContext.xml:

<bean id="inVMConnectionFactory" class="org.springframework.jndi.JndiObjectFactoryBean">
    <property name="jndiName">
        <value>java:/ConnectionFactory</value>
    </property>
</bean>

<bean id="cachedConnectionFactory" class="org.springframework.jms.connection.CachingConnectionFactory">
    <property name="targetConnectionFactory" ref="inVMConnectionFactory" />
</bean>

<bean id="producer" class="it.ubiquity.gestoreprofilazione.onweb.OnWebProducer" scope="singleton">
    <property name="queue" ref="retryQueue" />
    <property name="connectionFactory" ref="cachedConnectionFactory" />
</bean>

<bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">
    <property name="connectionFactory" ref="cachedConnectionFactory" />
    <property name="sessionTransacted" value="true" />
    <property name="sessionAcknowledgeMode" value="#{T(javax.jms.Session).CLIENT_ACKNOWLEDGE}" />
    <property name="pubSubDomain" value="false" />
    <property name="receiveTimeout" value="#    {T(org.springframework.jms.core.JmsTemplate).RECEIVE_TIMEOUT_NO_WAIT}" />
</bean>

<bean id="jmsTransactionManager" class="org.springframework.jms.connection.JmsTransactionManager">
    <property name="connectionFactory" ref="cachedConnectionFactory" />
</bean>

<bean id="consumer" class="it.ubiquity.gestoreprofilazione.onweb.OnWebConsumer" scope="singleton">
    <property name="queue" ref="retryQueue" />
    <property name="jmsTemplate" ref="jmsTemplate" />
    <property name="transactionManager" ref="jmsTransactionManager" />
</bean>

Проблема у меня довольно странная: в первый раз, когда я получаю сообщение, handleMessage не работает, поэтому я откатываю транзакцию. Потом больше ничего не происходит. Если я проверю консоль JMX, то увижу, что в очереди есть одно сообщение. Теперь, если я перезапускаю JBoss, сообщения приходят снова и снова, как и ожидалось.
Возможно, что-то не так с моей конфигурацией, но почему она работает после перезагрузки?

  • ХорнетQ 2.2.10
  • JBoss 5.1.0
  • Весна 3.1.2

ОБНОВЛЕНИЕ
При включенной отладке я впервые вижу:

DEBUG [org.springframework.jms.connection.JmsTransactionManager] (baseScheduler-1) Создание новой транзакции с именем [null]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT

и после первого отката, при последующем приеме и откате вижу:

DEBUG [org.springframework.jms.connection.JmsTransactionManager] (baseScheduler-1) Участие в существующей транзакции

Вместо этого после перезапуска JBoss я прочитал, что транзакция фактически откатывается:

DEBUG [org.springframework.jms.connection.JmsTransactionManager] (baseScheduler-1) Инициация отката транзакции 2012-11-05 09:54:14,436 DEBUG [org.springframework.jms.connection.JmsTransactionManager] (baseScheduler-1) Откат JMS транзакция на сеансе

Итак, почему откат происходит не с первого раза, а как только перезагружаю сервер происходит постоянно? Что я делаю неправильно?


person Carlo    schedule 31.10.2012    source источник


Ответы (1)


Хорошо, наконец-то мне удалось понять свою ошибку :) Во внешнем if's else я должен был зафиксировать транзакцию. Поэтому механизм работает после перезапуска JBoss: зависания транзакции нет.

person Carlo    schedule 05.11.2012