PDA

View Full Version : How do ClientAcknowlege take effect in JmsTemplate?



zjnbshifox
Nov 10th, 2005, 07:29 PM
When I set the ClientAcknowlege in JMS, According to JMS Spec,No. 15th message will redelivered,I must receive NO.15th Message in next receive operation.

But when I use the code below,it would skip No. 15th message, I can't receive the NO.15th Message anymore.
What is the problem in my code or configuration?


ApplicationContext ac = new FileSystemXmlApplicationContext("send.xml");
JmsTemplate jms = (JmsTemplate) ac.getBean("jmsTemplate");
jms.setSessionAcknowledgeMode(Session.CLIENT_ACKNO WLEDGE);
for(int i=1; i<100000;i++){
System.out.println(i);
try {
Message tm = jms.receive();
if(i == 15) throw new RuntimeException();
log.info("[" + tm.getStringProperty("SN") + "]");
tm.acknowledge();
} catch (Exception e) {
System.exit(0);
}
//tm.acknowledge();
}

My config file:


<bean id="dest" class="org.activemq.message.ActiveMQQueue">
<constructor-arg index="0" value="TestHUGE66.Queue" />
</bean>

<bean id="jmsFactory" class="org.activemq.pool.PooledConnectionFactory">
<property name="connectionFactory">
<bean class="org.activemq.ActiveMQConnectionFactory" init-method="start">
<property name="brokerURL" value="tcp://localhost:61616"/>
</bean>
</property>
</bean>

<bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">
<property name="connectionFactory">
<bean class="org.springframework.jms.connection.SingleConnectio nFactory">
<property name="targetConnectionFactory">
<ref local="jmsFactory"/>
</property>
</bean>
</property>
<property name="defaultDestination">
<ref bean="dest"/>
</property>
</bean>


ActiveMq use postgres8.0.4,jdbc drivers is postgresql-8.0-314.jdbc3.jar

zjnbshifox
Nov 20th, 2005, 09:45 PM
I tried the org.springframework.transaction.support.Transactio nTemplate to receive Message in transaction
my code:


TransactionTemplate tt = (TransactionTemplate)ac.getBean("transactionTemplate");
final JmsTemplate jms = (JmsTemplate) ac.getBean("jmsTemplate");
tt.execute(new TransactionCallback() {
public Object doInTransaction(TransactionStatus ts) {
try{
for(int i=0;i<10;i++){
Message tm = jms.receive();
if(i==5) throw new RuntimeException();
log.info("[" + tm.getStringProperty("SN") + "]");
}
}catch(Exception e){
ts.setRollbackOnly();
}
return null;
}
});


my configuratrion file is below:



<bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">
<property name="defaultDestination">
<ref bean="dest"/>
</property>
<property name="connectionFactory" ref="connectionFactory"/>
</bean>

<bean id="connectionFactory" class="org.activemq.ActiveMQConnectionFactory">
<!--<property name="brokerURL" value="tcp://localhost:61616" />-->
<property name="brokerURL" value="tcp://localhost:61616"/>
<property name="useEmbeddedBroker" value="false"/>
</bean>
<bean id="dest" class="org.activemq.message.ActiveMQQueue">
<constructor-arg index="0" value="TestHUGE77.Queue" />
</bean>
<bean id="transactionTemplate" class="org.springframework.transaction.support.Transactio nTemplate">
<property name="transactionManager">
<ref bean="jmsTransactionManager"/>
</property>
</bean>
<bean id="jmsTransactionManager" class="org.springframework.jms.connection.JmsTransactionM anager">
<property name="connectionFactory">
<ref local="connectionFactory" />
</property>
</bean>

I use the Activemq as the default configuration.
Here is the Information in console:


2005-11-21 11:38:50,109 DEBUG [org.springframework.jms.connection.JmsTransactionM anager] - Initiating transaction rollback
2005-11-21 11:38:50,109 DEBUG [org.activemq.TransactionContext] - Rolledback local transaction: null
2005-11-21 11:38:50,109 DEBUG [org.springframework.transaction.support.Transactio nSynchronizationManager] - Removed value [org.springframework.jms.connection.ConnectionHolde r@d251a3] for key [org.activemq.ActiveMQConnectionFactory@860d49] from thread [main]

I also can't receive the Message I want.
Is there any problem in my code or configuration.
PS:When I use the spring configuration to send Messages ,it is OK.
Any body give some suggestions?

jstrachan
Nov 21st, 2005, 03:41 AM
Note that the JmsTemplate will create a connection, session, consumer then close them all down again each time. So you should never use JmsTemplate with a regular JMS ConnectionFactory - there should be massive warnings all over the javadoc of JmsTemplate as its only intended for use inside a J2EE application server along with an application servers JCA provider of the JMS ConnectionFactory.

So I'd recommend using Message Driven POJOs with ActiveMQ instead...

http://jencks.org/Message+Driven+POJOs

If you absolutely insist on using JmsTemplate, which I don't recommend for consumption, then ensure you use Jencks to create a pooled version of the ConnectionFactory....

http://jencks.org/Outbound+JMS