I have a table that stores pending messages. To handle these messages I've created a TimerTask that triggers every 1 second. This task collects up to 100 messages to be handled and then creates a worker thread and passes the messages over to the worker for further processing.
This process is repeated as long as there are messages in the queue (another 100 messages are collected, and a new worker thread is created).
Now, the challenge lies in ensuring that the TimerTask does not collect the same messages repeatedly. The messages are collected using a JPQL query that picks the "first" messages in the message queue, based on priority. To avoid getting any of the same messages in the following queries, the collected messages must be flagged. I've chosen to do this in the following way:
First, the TimerTask updates messages with a timestamp (with a setMaxResults of 100) and also changes the status to 'PROCESSING'. Then another query collects messages that has the correct timestamp value AND has status 'PROCESSING'.
These messages are then forwarded to a worker thread.
The TimerTask now creates a new timestamp value and performs the sequence again.
This works fine. But problems occur when my worker threads process these messages. Some fields are updated, and then merged using em.merge(obj). What frequently happens is that most fields are updated correctly, but the status-field is often NOT updated. It remains as PROCESSING, even though I explicitly set it just before I call the session bean's update method.
For debugging purposes I've added prints to the bean method. It first prints the status of the entity being merged, then the status of the entity in the EntityManager (using the find-method). Then the entity is merged and lastly I print the status from the entity returned from the merge method.
The times this process works as it should, the EM-status before merge is (correctly) PROCESSING and then RETRY after merge. But the times this does NOT work, the EM-status before merge is not PROCESSING, but RETRY (since this is a retry-queue of failed messages). (btw: for testing, the worker never succeeds, returning the message to the retry queue).
It seems then, that there is an inconsistency between the EM (who states that the status is RETRY) and the database (which I monitor externally to see that the status is in fact PROCESSING. The latter is correct, since the TimerTask has just updated the status.
What might be causing this inconsistency? Both the TimerTask and the worker thread are using the same session bean, but different methods. The entity manager is injected into the bean using @PersistenceContext(unitName="MQServices"). My understanding is that both classes should then be using the same entity manager. There are no other applications or anything else that updates the database records simultaneously.
That was a lot of text. Thanks a lot for reading!
Marius
[Message sent by forum member 'mariusw' (mariusw)]
http://forums.java.net/jive/thread.jspa?messageID=273053