I'm implementing a similar scenario however i've come across a different problem, see
http://forums.java.net/jive/thread.jspa?threadID=26535&tstart=0.
If your function that processes a task takes a long time as recommended i would create a separate function that selects (and locks) the required records in a separate transaction.
To do this you can use the [b]toplink.Pessimistic-lock[/b] query hint with a value of [b]Lock[/b] (unfortunately this is broken for postgresql) or an explicitly add [b]FOR UPDATE[/b] to a native select query. Doing this will lock the records selected.
I've created a separate function that is annotated with
[b]@TransactionAttribute(value=TransactionAttributeType.REQUIRES_NEW)[/b]
which does the [i]select ... for update[/i] before returning the selected rows back to the main function. I'm not sure if it is required, but i've found i don't need to declare this function in the local interface and call it like a standard function - instead of getting a reference to the bean and calling it through the container.
for example:
@TransactionAttribute(value=TransactionAttributeType.REQUIRES_NEW)
public int getNextTaskID(){
int taskID=(Integer)em.createNamedQuery(query).setHint("toplink.pessimistic-lock","Lock").getSingleResult();
or
int taskID =(Integer)em.createNativeQuery("select xxx for update").getSingleResult();
// you can update the records here with out fear that another thread can access them
return taskID;
}
public void getTask(){
taskID=getNextTask();
// do something
}
Hope that helps
[Message sent by forum member 'jsl123' (jsl123)]
http://forums.java.net/jive/thread.jspa?messageID=217736