我正在尝试使用Spring和HornetQ来管理JMS事务 这是我写的代码:
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,消息将一次又一次地接收,如预期的那样 也许我的配置有问题,但为什么它在重启后有效呢?
更新
启用调试后,我第一次看到了:
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调试 [org.springframework.jms.connection.JmsTransactionManager] (baseScheduler-1)在Session
上回滚JMS事务
那么,为什么第一次没有发生回滚,并且一旦重新启动服务器,它就会一直发生?我做错了什么?
答案 0 :(得分:4)
好的,最后我成功理解了我的错误:) 在外部if的其他地方我应该提交交易。这就是重启JBoss后机制工作的原因:没有挂起任何事务。