Pregunta

Estoy usando hibernate 3 con c3p0 para un programa que extrae constantemente datos de alguna fuente y los escribe en una base de datos. Ahora el problema es que la base de datos podría no estar disponible por algunas razones (en el caso más simple: simplemente la apagué).

Si se va a escribir algo en la base de datos, no debería haber ninguna excepción: la consulta debe esperar toda la eternidad hasta que la base de datos vuelva a estar disponible. Si no me equivoco, esta es una de las cosas que el grupo de conexiones podría hacer por mí: si hay un problema con la base de datos, solo vuelva a intentar conectarse, en el peor de los casos para el infinito.

Pero en cambio obtengo una excepción de tubería rota, a veces seguida de una conexión rechazada y luego la excepción se pasa a mi propio código, lo que no debería suceder.

Incluso si encuentro la excepción, ¿cómo podría reiniciar limpiamente la hibernación nuevamente? (Hasta ahora, sin c3p0, simplemente construí la fábrica de sesiones nuevamente, pero no me sorprendería si eso pudiera filtrar conexiones (¿o está bien hacerlo?)).

La base de datos es la edición de código abierto Virtuoso.

Mi configuración hibernate.xml.cfg c3p0:

<property name="hibernate.connection.provider_class">org.hibernate.connection.C3P0ConnectionProvider</property>  
<property name="hibernate.c3p0.breakAfterAcquireFailure">false</property>
<property name="hibernate.c3p0.acquireRetryAttempts">-1</property>
<property name="hibernate.c3p0.acquireRetryDelay">30000</property>
<property name="hibernate.c3p0.automaticTestTable">my_test_table</property>

<property name="hibernate.c3p0.initialPoolSize">3</property>
<property name="hibernate.c3p0.minPoolSize">3</property>
<property name="hibernate.c3p0.maxPoolSize">10</property>

por cierto: la tabla de prueba se crea y obtengo toneladas de resultados de depuración, por lo que parece que en realidad lee la configuración.

¿Fue útil?

Solución

Bueno, parece que BoneCP realmente ha implementado esto. Se puede configurar para registrar la transacción y reproducirla en caso de falla de la red o la base de datos:

http: // jolbox.com/bonecp/downloads/site/apidocs/com/jolbox/bonecp/BoneCPConfig.html#setTransactionRecoveryEnabled(boolean)

Otros consejos

  

Si no me equivoco, esta es una de las cosas que el grupo de conexiones podría hacer por mí: si hay un problema con la base de datos, simplemente vuelva a intentar conectarse, en el peor de los casos para el infinito.

Estás equivocado. Un grupo de conexiones es simplemente ... un grupo de conexiones, contiene algunas conexiones físicas ya establecidas a la base de datos y se utiliza para evitar la sobrecarga de crear estas conexiones cuando necesita una de ellas.

Dicho esto, estas conexiones pueden volverse obsoletas (por ejemplo, si reinicia la base de datos). Afortunadamente, la mayoría de los grupos de conexiones se pueden configurar para probar si una conexión sigue siendo válida y para renovarlos antes de distribuirlos. c3p0 admite esta función como se documenta en Configuración de pruebas de conexión y está en realidad ya estoy usando una de las varias opciones. Por lo tanto, sus conexiones deben renovarse cuando vuelva la base de datos.

Pero no espere que su aplicación se suspenda mágicamente cuando la base de datos se caiga, un grupo no lo hará.

Gracias por la respuesta. Parece que realmente no he entendido el último párrafo de la sección http://www.mchange.com/projects/c3p0/index.html# configuring_recovery

Porque al principio parece que c3p0 podría hacerlo (detectar conexiones obsoletas y reintentar adquirir conexiones para toda la eternidad sin siquiera lanzar una excepción al código de la aplicación (a menos, por supuesto, cuando sea un error relacionado con la instrucción sql y no con el conexión), pero en el último párrafo, que está escrito de una manera bastante confusa, parece que c3p0 no puede asegurarlo al 100%.

Entonces, mi solución fue hacer un pequeño contenedor para los métodos que necesitaba de la interfaz de conexión jdbc, que intentan reconectarse si una consulta falla debido a un error de conexión. Por supuesto, es un poco raro, porque prefiero que mis componentes usen la interfaz de conexión estándar en lugar de mi propia interfaz, pero al menos ahora funciona de manera limpia.

Te estás olvidando:

  • ¿Qué pasa con sus transacciones que se han iniciado?
  • ¿Qué pasa con las declaraciones preparadas que ya se han enviado a la base de datos?
  • etc.

Por lo tanto, su aplicación tendrá que reiniciar la transacción. La única forma posible en la que puedo pensar es que el grupo de conexiones realice un seguimiento de cada llamada al manejador de conexiones y las reproduzca en caso de error, pero esto reduciría enormemente el grupo de conexiones.

En el caso de BoneCP ( http://jolbox.com ), el grupo detecta que ha ocurrido una falla por capturar la excepción lanzada por el controlador JDBC primero y manejarla marcando esa conexión como defectuosa o recreando todo el grupo de conexiones.

Editar: se está manejando ahora.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top