Volgens uw toewijzing zou de volgorde van bewerkingen er als volgt uit moeten zien:
Person p = DAO.findPerson(id);
Car car = new Car();
car.setPerson(p);
DAO.saveOrUpdate(car);
p.getCars().add(car);
Car firstCar = p.getCars().get(0);
firstCar.setPerson(null);
p.getCars().remove(firstCar);
if (p.officialCar.equals(firstCar)) {
p.officialCar = null;
p.officialCar.person = null;
}
DAO.delete(firstCar);
Een update of een verwijder betekent het verkrijgen van een exclusief slot , zelfs op READ_COMMITTED
isolatieniveau.
Als een andere transactie dezelfde rij wil updaten met de huidige lopende transactie (die deze rij in kwestie al vergrendelde), krijg je geen deadlock, maar een lock acquisitie time-out uitzondering.
Aangezien je een impasse hebt, betekent dit dat je sloten op meerdere tafels aanschaft en dat de vergrendelingen niet goed zijn besteld.
Zorg er dus voor dat de servicelaagmethoden de transactiegrenzen bepalen, niet de DAO-methoden. Ik zie dat je de get . hebt verklaard en vind methoden om ONDERSTEUND te gebruiken, wat betekent dat ze een transactie alleen zullen gebruiken als er momenteel een is gestart. Ik denk dat je daar ook REQUIRED voor moet gebruiken, maar markeer ze gewoon als read-only = true
.
Zorg er dus voor dat het transactie-aspect de transactiegrens op de "mijnmethode" toepast en niet op de DAO.