Search code examples
jakarta-eejpaglassfishlockingpessimistic-locking

Locking an entity


I currently facing a problem with locking an entity in JPA. I have a list of several entities from a database. For each element there's a edit button which loads a view for editing that entry. Every time a client tries to edit an entry, I want to check if the entity is locked preventing the client to even load the edit mask of the entity.

My method which loads the entity:

[...]
mail = (EMailKonto) query.getSingleResult();
System.out.println(getLock(mail).toString());
setLock(mail, LockModeType.PESSIMISTIC_WRITE);
System.out.println(getLock(mail).toString());

The called methods:

public void setLock(T entity, LockModeType lock) 
{
getEntityManager().lock(entity, lock);
}

public LockModeType getLock(T entity)
{
    return getEntityManager().getLockMode(entity);
}

What happens is that the first syso prints NONE, since there is no lock applied. Then the lock gets set and the second syso prints PESSIMISTIC_WRITE. When i refresh the page or use another tab / browser and click on the edit button of the same entity, the first syso should print PESSIMISTIC_WRITE, since I never remove the lock, but it again prints NONE. Could you guys help me to understand how to implement that kind of function?

Regards


Solution

  • Technically, the pessimistic lock is implemented via issuing the SELECT ... FOR UPDATE command, which locks the row(s) for the current transaction, so that any other SELECT ... FOR UPDATE as well as UPDATE in the other transaction will fail.

    All transaction-level locks are released when the transaction is ended, therefore such implementation is not feasible for the functionality you need, because you would need to keep transactions as long as the client is editing the row. It is possible to realize in heavy client (although a terrible design), but in web application is not realistic because you even don't have a feedback if the client closes the browser.

    You need to manually implement and manage locks at the business level, by storing the 'locks' in the separate table. Transaction-level (pessimistic) locks are not designed to function as business-level locks. They are low level mechanism designed to assert transaction consistency.