2009-03-16 15 views
5

Estoy intentando registrar la creación y destrucción de conexiones de bases de datos en nuestra aplicación utilizando c3p0's ConnectionCustomizer. En él, tengo un código que se ve así:Bloqueo de pedidos en C3p0

log(C3P0Registry.getPooledDataSources()) 

Me estoy quedando sin nada. Estoy descubriendo que c3p0 tiene al menos un par de objetos en su biblioteca que usan métodos sincronizados y no parecen especificar el orden de bloqueo previsto. Cuando registro las conexiones, mantengo un bloqueo en C3P0Registry y eventualmente PoolBackedDataSource (simplemente crear una lista de las fuentes de datos está accediendo al código hash que causa un bloqueo).

El apagado del proveedor de conexión (llamando al C3P0ConnectionProvider.close()) hace que se llamen los bloqueos en el orden opuesto. Pero mientras las fuentes de datos hijo se cierran, mi registro se está desencadenando. El resultado es un punto muerto.

Parece que tanto las llamadas que estoy haciendo en la biblioteca c3p0 son válidos, llamadas esperados:

  • C3P0ConnectionProvider.close()
  • C3P0Registry.getPooledDataSources()

También parece que (a menos que se indique expresamente en la documentación) debe ser la responsabilidad de la biblioteca administrar su propia estrategia de bloqueo. (No digo esto para culpar a nadie ... solo para confirmar mi comprensión de las mejores prácticas)

¿Cómo debo tratar este problema? Como c3p0 utiliza métodos sincronizados en lugar de un mecanismo más moderno, no puedo realmente probar los bloqueos.

Desde mi código de cierre DataSource, pude agarrar primero el cerrojo C3P0Registry antes de cerrar el DataSource. Estaría adivinando la orden de bloqueo correcta, que no sé si me siento cómodo.

No creo que pueda revertir el orden de bloqueo para la llamada de registro. Necesito el C3P0Registry para obtener la lista de DataSources, por lo que no pude bloquear el DataSources sin antes bloquear C3P0Registry para obtener referencias a ellos.

Otra solución, por supuesto, es proporcionar otro bloqueo de nivel superior por encima de todo c3p0. En el caso de un grupo de conexiones, eso parece vencer al punto.

Por ahora, estoy retrocediendo mi registro. Gracias por cualquier ayuda.

+0

Experimentando algo similar, interesado en si ha encontrado más información sobre esto. –

+0

Terminé agregando un bloque sincronizado alrededor del código que llama a close() para garantizar que obtengo bloqueos en el mismo orden que mi registro. Es descuidado, pero también lo es la estrategia de bloqueo en C3p0. –

Respuesta

0

No sé cómo solucionar el problema de bloqueo, pero creo que debería dar un paso atrás y pensar en el problema original. "Estoy intentando registrar la creación y destrucción de las conexiones de la base de datos en nuestra aplicación ..."

Recomendaría lo siguiente.

Crea una clase y haz que implemente javax.sql.DataSource. Cree un campo del mismo tipo y delegue todos los métodos en él. En el método getConnection(), devuelva su propia clase de conexión envolviendo alrededor de java.sql.Connection y así sucesivamente. Luego ajuste esta clase alrededor de su origen de datos original. En sus clases, ahora puede simplemente crear un registrador y registrar todas las acciones que desea ver en su registro.