Domanda

Ho un programma Java composto da circa 15 metodi. E questi metodi vengono invocati molto frequentemente durante la realizzazione del programma. Al momento, sto creando una nuova connessione in ogni metodo e invocando istruzioni su di essi (il database è impostato su un altro computer della rete).

Quello che vorrei sapere è: dovrei creare una sola connessione nel metodo principale e passarlo come argomento a tutti i metodi che richiedono un oggetto connessione poiché ridurrebbe in modo significativo il numero di connessioni oggetto nel programma, invece di creare e chiudere connessioni molto frequentemente in ogni metodo.

Sospetto di non utilizzare le risorse in modo molto efficiente con il progetto attuale e vi sono molte possibilità di miglioramento, considerando che questo programma potrebbe crescere molto in futuro.

È stato utile?

Soluzione

Sì, dovresti considerare di riutilizzare le connessioni anziché crearne una nuova ogni volta. La normale procedura è:

  • fai qualche ipotesi su quante connessioni simultanee il tuo database può gestire sensibilmente (es. inizia con 2 o 3 per CPU sul computer del database fino a scoprire che questo è troppo pochi o troppi-- tenderà a dipendere su come sono associate le tue query al disco)
  • crea un pool di queste numerose connessioni: essenzialmente una classe che puoi richiedere " la prossima connessione gratuita " all'inizio di ciascun metodo e poi "ripasso" al pool alla fine di ciascun metodo
  • il tuo metodo getFreeConnection () deve restituire una connessione gratuita se disponibile, altrimenti (1) crearne una nuova, fino al numero massimo di connessioni che hai deciso di autorizzare, oppure (2) se il massimo sono già stati creati, attendi che diventi gratuito
  • Consiglierei la classe Semaphore per gestire le connessioni; In realtà ho un breve articolo sul mio sito web su gestendo un pool di risorse con un semaforo con un esempio penso che potresti adattarti al tuo scopo

Un paio di considerazioni pratiche:

  • Per prestazioni ottimali, è necessario fare attenzione a non " hog " una connessione mentre non la stai effettivamente utilizzando per eseguire una query . Se prendi una connessione dal pool una volta e poi la passi a vari metodi, devi assicurarti di non farlo accidentalmente.
  • Non dimenticare di restituire le tue connessioni al pool! (prova / finalmente è il tuo amico qui ...)
  • Su molti sistemi, non è possibile mantenere le connessioni aperte "per sempre" : l'O / S le chiuderà dopo un tempo massimo. Quindi nel tuo metodo "restituisci una connessione al pool", dovrai pensare a "ritirare" connessioni che sono in circolazione da molto tempo (costruisci un meccanismo per ricordare, ad esempio avendo un oggetto wrapper attorno a un vero oggetto JDBC Connection che puoi utilizzare per memorizzare metriche come questa)
  • Puoi prendere in considerazione l'utilizzo di dichiarazioni preparate.
  • Nel tempo, probabilmente dovrai modificare le dimensioni del pool di connessioni

Altri suggerimenti

Puoi passare la connessione o meglio usare qualcosa come il Pool di connessioni al database di Jakarta. http://commons.apache.org/dbcp/

Dovresti usare un pool di connessioni per questo.

In questo modo potresti chiedere la connessione e rilasciarla quando hai finito e restituirla al pool

Se un altro thread desidera una nuova connessione e quella è in uso, è possibile crearne una nuova. Se nessun altro thread utilizza una connessione, lo stesso potrebbe essere riutilizzato.

In questo modo puoi lasciare la tua app in qualche modo com'è (e non passare la connessione tutt'intorno) e comunque usare le risorse correttamente.

Purtroppo i ConnectionPool di prima classe non sono molto facili da usare in applicazioni autonome (sono i valori predefiniti nei server delle applicazioni) Probabilmente un microcontenitore (come Sping) o un buon framework (come Hibernate) potrebbero consentirne l'uso.

Non sono però troppo difficili da codificarne uno da zero.

:)

Questa ricerca su Google aiuterà per saperne di più su come usarne uno.

Scorri

Molti driver JDBC eseguono il pool di connessioni per te, quindi in questo caso c'è poco vantaggio nel creare pool aggiuntivi. Ti suggerisco di consultare la documentazione per il tuo driver JDBC.

Un altro approccio ai pool di connessioni è

  • Avere una connessione per tutti gli accessi al database con accesso sincronizzato. Ciò non consente la concorrenza ma è molto semplice.
  • Memorizza le connessioni in una variabile ThreadLocal (ignora initialValue ()) Funziona bene se c'è un piccolo numero fisso di thread.

Altrimenti, suggerirei di utilizzare un pool di connessioni.

Se l'applicazione è a thread singolo o esegue tutte le operazioni del database da un singolo thread, è possibile utilizzare una singola connessione. Supponendo che non siano necessarie più connessioni per nessun altro motivo, questa sarebbe di gran lunga la più semplice implementazione.

A seconda del driver in uso, potrebbe anche essere possibile condividere una connessione tra i thread - anche questo andrebbe bene, se si ritiene che il driver non mentisca sulla sicurezza dei thread. Vedere la documentazione del driver per ulteriori informazioni.

In genere gli oggetti sottostanti " Connessione " non può essere utilizzato in modo sicuro da più thread, quindi in genere non è consigliabile condividere ResultSet, oggetti Statement ecc. tra i thread - di gran lunga la migliore politica è di usarli nello stesso thread che li ha creati; questo è normalmente facile perché quegli oggetti non sono generalmente tenuti troppo a lungo.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top