No. Kicsit beszélgettem ChatGPT barátunkkal (aki eléggé szeret félrebeszélni és tévutakra vezetni sajnos). Kb. ugyanoda lukadtunk ki a Pessimistic lock-al mint az optimistic lock-al. Az oka egyszerű. A különböző Entity Cache-k különböző állapotokat tárolhatnak és nem mindig vánszorog le szerinte a pessimistic lock sem a DB szintre és nem is mindig vánszorognak onnan fel a friss adatok, ha pl. a cache-ből szedi ki. Valamint az egész tranzakció végéig futhat több példány ismét, mert sokszor csak akkor tolja le a DB szintre a write lock-ot így akkor derül csak ki, hogy ütközés van.
Valami olyasmit javasolt végül, hogy külön tranzakcióban nyomjam le a foglaltságot a DB-be és külön EntityMAnager-ben:
@Stateless
public class ControlService {
@PersistenceContext
private EntityManager entityManager;
private static final String CONTROL_NAME = "processing_control";
public boolean isProcessing() {
EntityManager em = entityManager.getEntityManagerFactory().createEntityManager();
try {
em.getTransaction().begin();
Control control = em.find(Control.class, CONTROL_NAME, LockModeType.PESSIMISTIC_WRITE);
if (control == null) {
control = new Control();
control.setName(CONTROL_NAME);
control.setStatus("fut");
control.setLastStarted(new Date());
em.persist(control);
em.getTransaction().commit();
return false;
} else {
if (control.getStatus() == null) {
control.setStatus("fut");
control.setLastStarted(new Date());
em.merge(control);
em.getTransaction().commit();
return false;
} else {
em.getTransaction().commit();
return true;
}
}
} catch (Exception e) {
em.getTransaction().rollback();
// handle exception
} finally {
em.close();
}
return false;
}
public void finishProcessing() {
try {
Control control = entityManager.find(Control.class, CONTROL_NAME, LockModeType.PESSIMISTIC_WRITE);
control.setStatus(null);
entityManager.merge(control);
} catch (Exception e) {
// handle exception
}
}
}
Ez a megoldás sem tűnik jónak, mert ha jól tudom az EntityCache az EntityManagerFactory-nként van. Tehát megint csak beleesek a különböző Entity Cache problémáiba. Eddig volt olyan helyem ahol volt entity cache de csak egy nagy monolitikusban, volt ahol ki volt kapcsolva, ilyen még nem volt, hogy van is meg nincs is. :)
Esetleg egy külön DS megoldhatja ezt a gondot?