Oracle
 sql >> Database >  >> RDS >> Oracle

Perché Hibernate genera org.hibernate.exception.LockAcquisitionException?

Secondo la tua mappatura, la sequenza delle operazioni dovrebbe assomigliare a questa:

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);

Un aggiornamento o un elimina significa acquisire un blocco esclusivo , anche su READ_COMMITTED livello di isolamento.

Se un'altra transazione vuole aggiornare la stessa riga con la transazione corrente in esecuzione (che ha già bloccato questa riga in questione) non otterrai un deadlock, ma un timeout di acquisizione del blocco eccezione.

Dato che hai un deadlock, significa che acquisisci blocchi su più tabelle e le acquisizioni dei blocchi non sono ordinate correttamente.

Quindi, assicurati che i metodi del livello di servizio impostino i limiti della transazione, non i metodi DAO. Vedo che hai dichiarato il get e trova metodi per utilizzare SUPPORTED, il che significa che utilizzeranno una transazione solo se una è attualmente avviata. Penso che dovresti usare REQUIRED anche per quelli, ma contrassegnali semplicemente come read-only = true .

Quindi assicurati che l'aspetto della transazione applichi il limite della transazione sul "mitodo" e non su quelli DAO.