JPA2 Optimistick Lock

Hi I am struggling with Optimistick Lock on JPA2 and I have no more ideas why this is happening. My thing is I am running multiple threads, but there is one object in the database that saves the progress. This means that various threads try to update this object at runtime so that the user's progress can be seen.

I have methods addAllItems

and addDone

. Both methods are used to update an object by multiple threads and I show the result by showing (done/allItems)*100

.

The methods were simple in the beginning

@Transactional(propagation=Propagation.REQUIRES_NEW)
public void addAllItems(Long id, Integer items){
    Job job = jobDao.findById(id);
    job.setAll(job.getAll() + items);

    jobDao.merge(job);
}

@Transactional(propagation=Propagation.REQUIRES_NEW)
public void addDone(Long id, Integer done){
    Job job = jobDao.findById(id);
    job.setDone(job.getDone() + done);

    jobDao.merge(job);
}

      

When I realized that Optimistic Lock was working, I changed both methods by adding sync to the signature. This has no effect, so I added an update (from the entity manager) to make sure I have the current version. It didn't matter either. I also added a manual flush at the end, but still nothing better ...

Here is the final version of the method ( addAllItems

almost the same, only the difference is in the setter):

@Transactional(propagation=Propagation.REQUIRES_NEW)
public synchronized void addDone(Long id, Integer done){
    Job job = jobDao.findById(id);
    job = jobDao.refresh(job);
    job.setDone(job.getDone() + done);

    jobDao.merge(job);
    jobDao.flush();
}

      

Where the method jobDao.refresh

just calls the update on entityManager

. I am using eclipselink 2.40.

What else can I check? I am currently out of ideas ...

+3


source to share


1 answer


Since you are sure you are using a proxy (I assume you have configured it correctly PlatformTransactionManager

), you can try to use an explicit pessimistic lock inside a transaction - you usually don't need to do this, but if that fixes the problem ...

I suppose in your dao you have something like:

Job job = EntityManager.find(Job.class, jobId);

      



To force pessimistic locking, just change it to:

Job job = EntityManager.find(Job.class, jobId, LockModeType.PESSIMISTIC_WRITE);

      

Since you're just loading, modifying, saving and committing, this might be the right use case for pessimistic locking.

+1


source







All Articles