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.
Experimentando algo similar, interesado en si ha encontrado más información sobre esto. –
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. –