users@glassfish.java.net

Re: JPA - entityManager.flush()

From: <glassfish_at_javadesktop.org>
Date: Thu, 17 May 2007 14:38:50 PDT

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