sql >> Base de Datos >  >> RDS >> Mysql

Hibernate:Interbloqueo encontrado al intentar obtener el bloqueo

Debido a que los interbloqueos ocurren con tanta frecuencia, parece que algunos de los subprocesos de la aplicación mantienen bloqueos durante un período de tiempo prolongado.

Cada subproceso en la aplicación utilizará su propia conexión/conexiones de base de datos al acceder a la base de datos, por lo que, desde el punto de vista de la base de datos, dos subprocesos son dos clientes distintos que compiten por los bloqueos de la base de datos.

Si un subproceso mantiene bloqueos durante un período de tiempo prolongado y los adquiere en un orden determinado, y aparece un segundo subproceso adquiriendo los mismos bloqueos pero en un orden diferente, es probable que se produzca un interbloqueo (ver aquí para obtener detalles sobre esta causa frecuente de interbloqueo).

También se producen interbloqueos en las operaciones de lectura, lo que significa que algunos subprocesos también adquieren bloqueos de lectura. Esto sucede si los subprocesos ejecutan transacciones en REPEATABLE_READ nivel de aislamiento o SERIALIZABLE .

Para resolver esto, intente buscar usos de Isolation.REPEATABLE_READ y Isolation.SERIALIZABLE en el proyecto, para ver si esto se está utilizando.

Como alternativa, utilice el READ_COMMITTED predeterminado nivel de aislamiento y anotar las entidades con @Version , para manejar la concurrencia usando bloqueo optimista en su lugar.

También intente identificar las transacciones de ejecución prolongada, esto sucede a veces cuando @Transactional se coloca en el lugar equivocado y envuelve, por ejemplo, el procesamiento de un archivo completo en el ejemplo de un procesamiento por lotes, en lugar de realizar transacciones línea por línea.

Esta es una configuración de log4j para registrar la creación/eliminación de administradores de entidades y las transacciones comienzan/confirman/revierten:

   <!-- spring entity manager and transactions -->
<logger name="org.springframework.orm.jpa" additivity ="false">
    <level value="debug" />
    <appender-ref ref="ConsoleAppender" />
</logger >
<logger name="org.springframework.transaction" additivity ="false">
    <level value="debug" />
    <appender-ref ref="ConsoleAppender" />
</logger >
  1. ¿Puedo ejecutar de alguna manera una consulta de actualización (ya sea JPA/Native) sin tener que bloquear la tabla a través de @Transactional?

Las consultas de actualización son posibles a través de consultas nativas o JPQL .

  1. ¿Puedo entrar de alguna manera en la sesión sin usar @Transactional? Por ejemplo, el subproceso programado intenta leer el campo diferido en los rendimientos de la entidad a LazyInitializationException:no hay sesión, si el método no está anotado con @Transactional

En métodos sin @Transactional , las consultas se ejecutarán en su propio administrador de entidades y devolverán solo entidades separadas, ya que la sesión se cierra inmediatamente después de ejecutar la consulta.

entonces las excepciones de inicialización perezosas en métodos sin @Transactional es normal. Puede establecerlos en @Transactional(readOnly=true) también.