2009-03-16 16 views
5

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.

+0

Sperimentare qualcosa di simile, interessato a sapere se hai trovato maggiori informazioni al riguardo. –

+0

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. –

risposta

0

Non so come risolvere il problema di blocco, ma penso che dovresti fare un passo indietro e pensare al problema originale. "Sto cercando di registrare la creazione e la distruzione delle connessioni al database nella nostra applicazione ..."

Vorrei raccomandare quanto segue.

Creare una classe e implementarla javax.sql.DataSource. Creare un campo dello stesso tipo e delegare tutti i metodi ad esso. Nel metodo getConnection() restituisce la propria classe Connection avvolgendo java.sql.Connection e così via. Quindi racchiudi questo corso attorno all'origine dati originale. Nelle classi ora puoi semplicemente creare un logger e registrare tutte le azioni che vuoi vedere nel tuo log.

Problemi correlati