2009-11-10 2 views

risposta

3

La pagina di intro di Apache DBCP riassume bene:

creazione di una nuova connessione per ogni utente può richiedere molto tempo (spesso che richiedono più secondi di orologio tempo), al fine di eseguire un database transazione che potrebbe richiedere millisecondi. L'apertura di una connessione per l'utente può non essere possibile in un'applicazione di servizio pubblico ospitata pubblicamente in cui il numero di utenti simultanei può essere molto grande. Di conseguenza, gli sviluppatori di spesso desiderano condividere un "pool" di connessioni aperte tra tutti gli utenti correnti dell'applicazione. Il numero di utenti effettivamente eseguendo una richiesta in un dato momento è di solito una piccola percentuale di il numero totale di utenti attivi, e durante l'elaborazione della richiesta è l'unica tempo una connessione database richiesto. L'applicazione registra nel DBMS e gestisce internamente tutti i problemi relativi all'account utente .

Quanto sono efficienti? Dipende dall'implementazione. In genere, mi aspetto che un pool installi le connessioni all'avvio o su richiesta. La prima connessione richiederà una connessione reale al database e, successivamente, quando si richiede una connessione, verrà fornita una connessione in pool esistente. Quindi la prima richiesta di connessione impiegherà più tempo, e in seguito dovrai solo prelevare oggetti da una raccolta (molto veloce).

+1

Dal Sachin ha chiesto in modo specifico a quali pool possono essere rivolte le prestazioni, aggiungo che generalmente hanno senso solo in un cli applicazione ent-server, in cui si hanno meno connessioni rispetto agli utenti. In particolare, non avrebbero senso in un'app thick-client in cui un utente si connette a un database. –

1

Creazione di connessioni ai database sono operazioni molto costose. I pool di connessioni sono istanze di connessioni al database che vengono create e memorizzate nella cache. Ogni volta che si desidera una nuova connessione a un database, viene utilizzato uno dal pool invece di creare una nuova connessione. Alcune piattaforme come .NET + SQL Server utilizzano i pool di connessione per impostazione predefinita (non è necessario crearne di propri). Quindi, in pratica migliorano le prestazioni risparmiando tempo creando nuove connessioni ogni volta.

1

Utilizzando un pool di connessione, si risparmia tempo ad ogni accesso poiché la connessione è già stabilita.

Inoltre, almeno su Oracle, si mantiene la dichiarazione compilata collegata alla connessione, quindi l'esecuzione ripetitiva della stessa istruzione SQL è ancora più rapida.

(vedi PreparedStatement se siete in Java/JDBC)

L'unico rischio di contro-prestazioni è quando si tiene troppe connessioni inattive in piscina, i ressources associati (il tuo lato e database) sono sprecati .

+0

Ricordare che le connessioni bloccano anche le risorse (thread, buffer) nel server. E una connessione stabilita viene sempre autenticata tramite una specifica coppia di utenti/password. Quindi, se il pool di connessioni funziona solo, quando tutte le connessioni utilizzano lo stesso account di database –

+0

Sì, hai perfettamente ragione con la preoccupazione relativa all'account del database univoco. (Questo può essere un problema durante la migrazione dall'applicazione C/S al web, ad esempio, se l'autorizzazione è in DB, in base all'utente connesso.) – Fouteier

0

La creazione di una connessione al database può essere o meno un'operazione costosa, a seconda del proprio ambiente e di ciò che si intende fare con esso.

Se si sta per eseguire una sola query molto semplice, la connessione probabilmente richiede più tempo (o più) della query.

Alcuni database hanno un overhead di connessione molto più grande di altri; se ottimizzato correttamente, mysql dovrebbe avere pochissimo (sopra il tempo per fare una connessione TCP e fare l'handshake del protocollo). Tuttavia, se la latenza sul server è molto alta, anche questa può essere abbastanza significativa (in particolare se si intende fare solo alcune query).

Se si prevede di fare, ad esempio, 100 query o alcune query molto lente, il tempo di connessione scompare in insignificanza.

In generale, direi di aprire una nuova connessione ogni volta finché non si può dimostrare che si tratta di un problema di prestazioni reali. Utilizzando il pool di connessioni può portare a bug, che non ci piace: Stato

  • collegamento non è stato completamente azzerato dopo l'uso precedente in piscina - così uno stato si sofferma e crea un comportamento imprevisto con conseguente un bug
  • connessione è stata chiusa in qualche modo (magari da un timeout firewall stateful) che non può essere rilevato, quindi, un'applicazione tenta di utilizzare una connessione chiusa, provocando un lungo ritardo o mancata
+0

Per un ambiente Web non si vuole ottenere una connessione (da un pool o in altro modo) all'inizio di una query, eseguire centinaia di query, quindi chiuderla. Ciò blocca in modo efficace la connessione (che è una risorsa limitata sul lato del database) e limita quindi il numero di utenti che il sito Web può supportare. Molto meglio prendere dal pool, usare, rimettere in piscina (prima di qualsiasi codice che impiega molto tempo). Considerando che il supporto dei pool di connessioni è costituito da poche righe di codice (una sola volta nella classe di utilità del gestore dati sorgente dati), non ci sono scuse per non usarle. – JeeBee

1

dai un'occhiata alla BoneCP (http://jolbox.com) nella sezione di riferimento per alcuni numeri. Ricorda che le condizioni preparate ecc. Sono legate a una connessione, quindi dovrai prepararle di nuovo e di nuovo se hai a che fare con le connessioni (un pool di connessioni memorizzerà le cache anche per te).

mio migliore soluzione finora: Utilizzare un lazyDataSource che si dà solo una connessione quando si ha realmente bisogno (cioè non alla cieca - se i dati possono provenire da una cache allora si può evitare il colpo database)

6

tuo la domanda è un po 'ambigua:

Vuoi homegrow un'implementazione del pool di connessioni? Se è così, questo è un buon punto di partenza: http://java.sun.com/developer/onlineTraining/Programming/JDCBook/conpool.htmlMa questo è altamente sconsigliato per gli ambienti di produzione. È consigliabile utilizzare un'API di pool di connessioni esistente e collaudata, come DBCP o C3P0.

Oppure si desidera sapere come utilizzare un pool di connessioni? In tal caso, la risposta dipende dall'API del pool di connessioni che stai utilizzando. Fortunatamente è solitamente disponibile sul sito Web dell'API in questione.

Oppure si desidera sapere quando/perché utilizzare un pool di connessioni? In tal caso, migliorerà sicuramente le prestazioni di connessione se si dispone di un'applicazione di lunga durata (ad esempio un'applicazione web) e sarà necessario connettere il database più spesso. La normale pratica JDBC è la seguente: acquisire e chiudere Connection, Statement e ResultSet nello spazio disponibile più breve (ovvero all'interno dello stesso blocco di metodo). Poiché la connessione è abbastanza costosa e può richiedere fino a 200 ms di tempo o anche di più, l'utilizzo di un pool di connessioni è molto più veloce. Fornisce connessioni su richiesta e si occupa di chiudere effettivamente la connessione. Ciò tuttavia non significa che potresti cambiare il modo in cui scrivi JDBC, ma devi ancora acquisirli e chiuderli nel più ambito possibile. L'unica cosa che devi cambiare è il modo in cui acquisisci la connessione. Per esempio.cambiare da

connection = driverManager.getConnection(); 

a sono necessari fino a quando il codice JDBC è ben scritto

connection = connectionPool.getConnection(); 

Niente più modifiche.

1

Creazione di pool di connessione al database con Tomcat

1. Tomcat entrare risorsa interna: conf/context.xml

Mettere le voci di risorsa nel file di context.xml:

<!-- jdbc/jndiName jndi --> 
<Resource name="jdbc/jndiName" auth="Container" type="javax.sql.DataSource" initialSize="1" maxActive="100" maxIdle="30" maxWait="10000" username="enter username" password="enter password" driverClassName="diver name" url="jdbc database url"/> 

2. Creare una classe che creerà il pool di connessioni

public class MyConnectionFactory { 
    private static String module = "[ QuoteConnectionFactory ]"; 
    private static QuoteConnectionFactory connectionFactory; 

    protected QuoteConnectionFactory() { 
    } 

    /** 
    * 
    * @return=>getInstance() is a static method which will return the instance 
    *      of its own class 
    */ 
    public static QuoteConnectionFactory getInstance() { 
     if (connectionFactory == null) 
      connectionFactory = new QuoteConnectionFactory(); 
     return connectionFactory; 
    } 

    /** 
    * 
    * @param jndiName 

    */ 
    public Connection getConnection(String jndiName) { 
     System.out.println("jndiName=======" + jndiName); 
     Connection conn = null; 
     InitialContext cxt = null; 
     DataSource dataSource = null; 
     try { 
      cxt = new InitialContext(); 
      Context envContext = (Context)cxt.lookup("java:/comp/env"); 
      dataSource = (DataSource)envContext.lookup(jndiName); 
     } catch (NamingException e) { 

     } catch (Exception e) { 

     } 

     if (dataSource == null) { 

      try { 
       conn = dataSource.getConnection(); 
      } catch (Exception e) { 

      } 

      System.out.println("connection===================" + conn); 
      return conn; 
     } 
    } 

3. Modifica file web.xml

<resource-ref> 
    <description>DB Connection</description> 
    <res-ref-name>jdbc/jndiName</res-ref-name> 
    <res-type>javax.sql.DataSource</res-type> 
    <res-auth>Container</res-auth> 
</resource-ref> 

4. Utilizzo in codice

Connection con= QuoteConnectionFactory.getInstance(). getConnection("jndiName");