2011-09-08 17 views
5

stiamo vedendo le situazioni in cui la nostra connessione al database da org.apache.commons.dbcp.BasicDataSource sta morendo con errori di scrittura di socket:rendimenti DBCP le connessioni chiuse

com.microsoft.sqlserver.jdbc.SQLServerException: Connection reset by peer: socket write error 

Tutti i tentativi successivi di scrivere alla connessione fallire, ovviamente:

com.microsoft.sqlserver.jdbc.SQLServerException: The connection is closed. 

Dopo aver aggiornato il codice per rilevare tali eccezioni e richiedere una nuova connessione quando si verifica, ha fallito nuovamente. Ho ragione nel sospettare che chiamare lo DataSource#getConnection() non stia effettivamente dando una nuova connessione ogni volta che viene chiamato? Non sta solo riutilizzando la connessione esistente, che è chiusa?

Se ho ragione, qual è il modo giusto per gettare via la vecchia connessione e richiederne una nuova?

EDIT: Ecco una versione più succinta di quello che mi piacerebbe sapere:

Connection c1, c2; 
c1 = DatabaseManager.getConnection(); 
// c1.close() not called 
c2 = DatabaseManager.getConnection(); 

Is "c1 == c2" una vera dichiarazione? O sono state assegnate due connessioni? E se è quest'ultimo, sarebbe il codice come questo rappresentano un "pool di connessioni fuga":

Connection c1; 
c1 = DatabaseManager.getConnection(); 
// c1.close() not called 
c1 = DatabaseManager.getConnection(); 

risposta

10

La connessione in pool è stata chiusa dal DB. Ciò può significare 2 cose:

  1. Il pool di connessioni mantiene le connessioni aperte troppo a lungo.
  2. Il DB chiude le connessioni dopo un tempo troppo breve.

In teoria, aumentare/diminuire il timeout su entrambi i lati per allinearlo dovrebbe risolvere il problema.

Su DBCP, la soluzione migliore è convalidare le connessioni prima di tornare con una testOnBorrow=true e un'impostazione validationQuery, ad es. SELECT 1. È possibile trovare le opzioni di configurazione nel Tomcat JDBC data sources documentation.


Aggiornamento secondo il vostro aggiornamento:

Ecco una versione più succinta di ciò che mi piacerebbe sapere:

Connection c1, c2; 
c1 = DatabaseManager.getConnection(); 
// c1.close() not called 
c2 = DatabaseManager.getConnection(); 

Is "c1 == c2" un affermazione vera? O sono state assegnate due connessioni?

Sono due connessioni distinte. Solo se chiami il numero c1.close(), c'è una ragionevole possibilità che lo c2 restituisca la stessa connessione.

E se è quest'ultimo, sarebbe il codice come questo rappresentano un "pool di connessioni fuga":

Connection c1; 
c1 = DatabaseManager.getConnection(); 
// c1.close() not called 
c1 = DatabaseManager.getConnection(); 

Sì, sicuramente vi saranno perdite la prima connessione, come non è mai stata restituita al pool .È necessario sempre chiudere tutte le risorse DB nel più breve ambito possibile in un blocco try-finally. Un pool di connessioni un po 'decente è comunque configurabile per raccogliere connessioni abbandonate, ma questo non dovrebbe assolutamente essere usato come "soluzione alternativa".

+0

Supponevo che la connessione fosse chiusa a causa dell'errore di scrittura socket precedentemente menzionato? Una volta chiuso, però, chiamando getConnection() ottiene una nuova connessione? –

+0

No, la chiusura di una connessione in pool lo restituirà al pool (è per questo che dovresti SEMPRE chiudere le connessioni in "finally", altrimenti il ​​pool potrebbe rimanere senza connessioni). Il resto della gestione delle connessioni interrotte dipende dal pool che dovresti controllare tramite la configurazione. Dovresti comunque capire che DBCP è un pool mal implementato. Vedi anche http://stackoverflow.com/questions/520585/connection-pooling-options-with-jdbc-dbcp-vs-c3p0/3481821#3481821 – BalusC

+0

Ma cosa succede se close() non viene mai chiamato? Cosa succede se il codice continua a chiamare getConnection()? riutilizza ancora la vecchia connessione chiusa o ottiene una nuova connessione dal pool? –

0

Anche io ho dovuto affrontare gli stessi problemi. poi mi sono reso conto che stavo facendo più chiamate ajax asincrone che stava causando il problema.

Ho serializzato le chiamate e ha risolto il problema.

+0

Si prega di inviare qualsiasi codice rilevante per i futuri richiedenti la risposta. – GibralterTop

Problemi correlati