Sto tentando di registrare la creazione e la distruzione delle connessioni del database nella nostra applicazione utilizzando ConnectionCustomizer
di c3p0. In esso, ho un codice simile al seguente:Ordine di blocco in C3p0
log(C3P0Registry.getPooledDataSources())
Sono in esecuzione deadlock. Sto scoprendo che c3p0 ha almeno un paio di oggetti nella sua libreria che usano metodi sincronizzati, e non sembrano specificare il loro ordine di blocco previsto. Quando registro le connessioni, sono in attesa di un blocco su C3P0Registry
e infine su PoolBackedDataSource
(la semplice creazione di un elenco di origini dati sta accedendo al codice hash causando un blocco).
L'arresto del provider di connessione (chiamando C3P0ConnectionProvider.close()
) provoca la chiamata dei blocchi nell'ordine opposto. Ma mentre le origini dati secondarie vengono arrestate, il mio log viene attivato. Il risultato è un punto morto.
Sembra che entrambe le chiamate che sto facendo in biblioteca c3p0 sono valide, chiamate attesi:
C3P0ConnectionProvider.close()
C3P0Registry.getPooledDataSources()
Sembra anche come (se non esplicitamente indicato nella documentazione) dovrebbe essere responsabilità della biblioteca gestire la propria strategia di blocco. (Non dico questo per incolpare qualcuno .. solo per confermare la mia comprensione delle migliori pratiche)
Come devo affrontare questo problema? Dal momento che c3p0 utilizza metodi sincronizzati piuttosto che un meccanismo più moderno, non posso realmente testare i blocchi.
Dal mio codice di chiusura DataSource
, ho potuto prima afferrare il blocco C3P0Registry
prima di chiudere lo DataSource
. Sarei indovinare l'ordine di blocco corretto, che non so se mi sento a mio agio con.
Non penso di poter annullare l'ordine di blocco per la chiamata di registrazione. Ho bisogno dello C3P0Registry
per ottenere l'elenco di DataSources
, quindi non potevo bloccare lo DataSources
senza prima bloccare C3P0Registry
per ottenere riferimenti ad essi.
Un'altra soluzione, ovviamente, è quella di fornire un altro blocco di livello superiore sopra tutto c3p0. Nel caso di un pool di connessioni, ciò sembra sconfiggere il punto.
Per ora, sto ripristinando il mio registro. Grazie per qualsiasi aiuto.
Sperimentare qualcosa di simile, interessato a sapere se hai trovato maggiori informazioni al riguardo. –
Ho finito per aggiungere un blocco sincronizzato attorno al codice che chiama close() per garantire che sto ottenendo dei lock nello stesso ordine del mio logging. È sciatto, ma ripeto, così è la strategia di blocco in C3p0. –