We have an application which reads messages from a JMS queue in a multithreaded scenario using Spring. Simplified version of our Runnable.run() method, being executed by two threads, is as follows:
The problem we're seeing is that, sometimes, if one of the threads is between the getTransaction() (line 8) and commit() (line 21) calls (eg if the call to ingest(putTask) is taking a long time), the second thread will continually timeout while calling receiveAndConvert(), and return null, even if there are other messages waiting on the queue. The behaviour is not consistent, however, and sometimes the next message can be read regardless. I *can* get consistent behaviour (timing out and returning null) by running Eclipse in debug mode though. Does anyone know what we're doing wrong? Or is this a bug? I realise I've missed out some (irrelevant) methods, the field declarations, and the application context. If any of these are needed for someone to provide help I will happily post them.
Joined: May 23, 2008
Aha, I've just found I can prevent this behaviour by changing the queuePrefetch value on the PrefetchPolicy of my ConnectionFactory from 1 to 0. What I don't understand is why the prefetch behaviour only comes into effect when I'm using transactions though. Also, if thread 1 has read a message (and presumably prefetched the next), I can pause this thread after it's transaction has been commited, and get thread 2 to read the second message instead. My understanding was that a prefetch policy greater than 0 would mean thread 1 would pre-allocate the two messages for itself and thread 2 wouldn't be able to consume either...?
subject: JmsTemplate.receiveAndConvert() times out if another thread is mid-transaction