I'm handling concurrency updates in to MySQL database. I'm using OptimisticLock.
Let's say I've table Job and table Person. I'm using OptimisticLock on the Job table. When an OptimisticLockException occurs I still want to update a field in the Person table but I'm not capable of doing so because the transaction as been marked for rollback (TransactionRolledbackLocalException).
Here's my code:
public Operation accept(Person person, long jobId) throws LockedRowException {
(...)
job.setPersonSelectedCardId(person.getSelectedCardId());
job.setLastEventDate(currentTime);
job.setStatus(OperationStatus.ACCEPTED.getStatus());
try {
// Update job with optimistic lock
jobDAO.editWithOptimisticLock(job);
} catch (LockedRowException ex) {
// Here I want to update the person table but
// it is not updating it because the transaction
// is marked to be rolled back
setPersonNrAcceptedJobsAndUpdateScore(person);
throw new LockedRowException(ex);
}
(...)
}
In the catch clause I want to update a person in the Person table. So my question is, how can I update the Person table when the transaction has been marked for rollback from an OptimisticLock caused in the Job table?
I'm using JavaEE with JPA and MySQL on Glassfish.
EDIT:
This is for a RESTful server. I still need to throw an exception inside the catch to notify my endpoint that will notify the user with a CONFLICT response. So I need to throw an exception to the upper level.
EDIT2:
My LockedRowException is a custom exception that is throw on my Abstract class that implements the JPA edit/merge/flush methods:
public class LockedRowException extends Exception {
private final OptimisticLockException optimisticLockException;
private final Exception exception;
public LockedRowException(OptimisticLockException optimisticLockException) {
super("Locked Transaction Exception - Entity was locked.");
this.optimisticLockException = optimisticLockException;
this.exception = null;
}
public LockedRowException(Exception exception) {
super("Locked Transaction Exception - Entity was locked.");
this.optimisticLockException = null;
this.exception = exception;
}
public LockedRowException(OptimisticLockException optimisticLockException, Exception exception) {
super("Locked Transaction Exception - Entity was locked.");
this.optimisticLockException = optimisticLockException;
this.exception = exception;
}
public OptimisticLockException getOptimisticLockException() {
return optimisticLockException;
}
}
Here's my edit method in my abstract class:
public void editWithOptimisticLock(T entity) throws LockedRowException {
getEntityManager().lock(entity, LockModeType.WRITE);
try {
mergeAndFlush(entity);
}
catch(org.eclipse.persistence.exceptions.OptimisticLockException ex) {
logger.warn("Concurrency detected - Entity: {}", entity.getClass().getSimpleName());
throw new LockedRowException(new OptimisticLockException(entity));
}
catch(OptimisticLockException ex) {
logger.warn("Concurrency detected - Entity: {}", entity.getClass().getSimpleName());
throw new LockedRowException(new OptimisticLockException(entity));
}
catch(RuntimeException re) {
logger.warn("Concurrency detected - Entity: {}", entity.getClass().getSimpleName());
throw new LockedRowException(new OptimisticLockException(entity));
}
}
Aucun commentaire:
Enregistrer un commentaire