sql >> Base de Datos >  >> RDS >> Oracle

¿Por qué Hibernate lanza org.hibernate.exception.LockAcquisitionException?

De acuerdo con su mapeo, la secuencia de operaciones debería verse así:

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

Una actualización o un eliminar significa adquirir un bloqueo exclusivo , incluso en READ_COMMITTED nivel de aislamiento.

Si otra transacción desea actualizar la misma fila con la transacción en ejecución actual (que ya bloqueó esta fila en cuestión), no obtendrá un interbloqueo, sino un tiempo de espera de adquisición de bloqueo excepción.

Dado que tiene un punto muerto, significa que adquiere bloqueos en varias tablas y las adquisiciones de bloqueos no están ordenadas correctamente.

Por lo tanto, asegúrese de que los métodos de la capa de servicio establezcan los límites de la transacción, no los métodos DAO. Veo que declaraste el get y buscar métodos para usar SOPORTADO, lo que significa que usarán una transacción solo si ya se ha iniciado. Creo que también debería usar REQUERIDO para esos, pero simplemente márquelos como read-only = true .

Así que asegúrese de que el aspecto de la transacción aplique el límite de la transacción en "mymethod" y no en los de DAO.