Pregunta Hibernate prepareConnection / preparedStatement issues


Dentro de nuestro proyecto, hemos actualizado Spring to 4.3.14.RELEASE e hibernar a 4.3.11.Final y desde que comenzamos a ver dos advertencias:

  1. WARN JDBC La conexión para restablecer no es idéntica a la conexión preparada originalmente: asegúrese de utilizar el modo de liberación de la conexión ON_CLOSE (valor predeterminado) y ejecutar contra Hibernate 4.2+ (o cambie el indicador prepareConnection de HibernateJpaDialect a falso

    • La cura es cambiar el modo de liberación a ON_CLOSE, lo que no queremos - cuando nuestra aplicación está bajo una gran carga, en algún momento deja de liberar las conexiones y la aplicación se atasca. Esto funciona correctamente con el modo de liberación AFTER_TRANSACTION.
    • El mensaje no dice qué sucede si se ignora este error. Google no muestra nada definitivo
    • ¿Qué pasa si cambiamos el prepareConnection bandera para false? Traté de encontrar ese indicador en la configuración de Hibernate pero no pude encontrarlo.
  2. GooGooStatementCache: 441 - ¡Declaración multiplicada preparada!

    • ¿Está esta advertencia relacionada con la anterior? ¿Es algo de lo que deberíamos preocuparnos?

EDITAR: He actualizado Hibernate a 5.2.13.Final.


6
2018-02-19 05:31


origen


Respuestas:


Aquí está la explicación de las declaraciones preparadas de forma múltiple (del Fuente de GooGooStatementCache)

La misma declaración ya ha sido preparada por esta Conexión,   y esa otra instancia aún no se ha cerrado, por lo que el grupo de instrucciones   tiene que preparar un segundo objeto PreparedStatement en lugar de reutilizarlo   la declaración previamente almacenada en caché. La nueva declaración será almacenada en caché, en caso   con frecuencia necesita varias copias de esta Declaración.

En inglés, lo que esto significa es lo mismo. PreparedStatement fue verificado desde un Connection antes de lo mismo PreparedStatement de la misma Connection fue registrado. Esto es inusual. Solo un cliente y Thread típicamente interactúa con un Connection a la vez, y generalmente uno reutilizaría el mismo PreparedStatement (reiniciando sus parámetros) si es requerido varias veces. Probablemente la razón más probable por la que esto sucede es porque la aplicación no close() el PreparedStatements que se abre, confiando en c3p0 para limpiarlos en Connection registrarse.

En cualquier caso, no es un problema de corrección, c3p0 manejará el caso muy bien. Pero probablemente refleja un código que podría ser limpiado un poco (ya sea por close()-ing  PreparedStatements inmediatamente después de usarlos o reutilizarlos) para ser más eficientes en el uso de recursos y memoria. Si está utilizando la versión actual (0.9.5.2), c3p0 debería haberle mostrado el texto de la problemática. PreparedStatement.


No sé por qué está viendo la advertencia de Primavera / Hibernación. c3p0 desprotegido Connections son proxies, pero sus identidades no cambian dentro de los ciclos de vida visibles por el cliente. Mirando un poco al fuente, hay algo de reflexión e indirección en obtener el Connection asociado con un Session, que luego se compara con el que se prestó. Quizás algo causa el Session para actualizar su asociado Connectionincluso mientras el Connection y Session están en uso? Desearía poder ser de más ayuda, pero no estoy seguro de lo que está pasando.


4
2018-02-21 06:18



Puedes probar con la propiedad hibernate.connection.handling_mode

hibernate.connection.handling_mode=DELAYED_ACQUISITION_AND_HOLD

Si está utilizando JTA

hibernate.connection.handling_mode=DELAYED_ACQUISITION_AND_RELEASE_AFTER_TRANSACTION

o

hibernate.connection.handling_mode=DELAYED_ACQUISITION_AND_RELEASE_AFTER_STATEMENT

mira esto springframework javadoc sección setPrepareConnection


0
2018-02-22 10:34



Tuve el mismo problema utilizando Tomcat JDBC Pool.

El problema viene en primavera porque hacen una verificación de igualdad en la línea 351 HibernateJpaDialect

La comparación se realiza en una Conexión dirigida por el Grupo de conexiones (ya sea Tomcat Pool o c3p0 en su caso).

Si configura ON_CLOSE (comportamiento heredado en hibernación), la conexión solo se cierra cuando la sesión se restablece / cierra, lo que no plantea ningún problema, pero puede cambiar el rendimiento, especialmente si el cliente mantiene abiertas las sesiones de Hibernate por un tiempo.

Si configura (predeterminado) AFTER_TRANSACTION, la conexión se libera después de que se complete la transacción y antes del cierre de la sesión. línea 301 JdbcCoordinatorImpl

Normalmente, este método resetSessionState () verifica que no se cierre una conexión dos veces línea 349  if (this.preparedCon != null && this.session.isConnected())

El problema viene porque la conexión (distribuida por el grupo de conexiones) cambió durante la primera versión (después de la transacción) y no se cumple la igualdad lo que causa el mensaje de advertencia. Este mensaje de advertencia es falso positivo


0
2018-06-26 16:14