View Full Version : [Java] Pool di connessioni JDBC
Ciao ragazzi,
ho una domanda riguardo il pool di connessioni JDBC. In pratica, le connessioi vengono memorizzate e poi passate ad altri utenti senza crearne di nuove. Ma se io accedo ad un database mediante username e password, come fa a passarmi una connessione già esistente? Devo comunque specificare i miei parametri di login. Quindi forse quello che non rifà è il caricamento e la registrazione del driver JDBC?
Dai ragazzi, nessuno usa pool di connessioni?
Anche io ho lo stesso porblema.. ma qui sembra che nessuno lo sappia... :P
io ho trovato mille modi diversi.. ma non so quale usare..
1) fare la classe da solo
package conn;
import java.io.Serializable;
import java.util.*;
import java.sql.*;
// La classe che gestisce un pool di connessioni
public class ConnectionPool implements Serializable{
// La variabile che gestisce l'unica istanza di ConnectionPool
private static ConnectionPool connectionPool = null;
private Vector freeConnections; // La coda di connessioni libere
private String dbUrl; // Il nome del database
private String dbDriver; // Il driver del database
private String dbLogin; // Il login per il database
private String dbPassword; // La password di accesso al database
// Costruttore della classe ConnectionPool
private ConnectionPool() throws ConnectionPoolException {
freeConnections = new Vector(); // Costruisce la coda delle connessioni libere
loadParameters(); // Carica I parametric per l'accesso alla base di dati
loadDriver(); // Carica il driver del database
}
// Funzione privata che carica i parametri per l'accesso al database
private void loadParameters() {
dbUrl = "jdbc:mysql://localhost:3306/[nomeDB]"; // Url per un database locale
dbDriver = "com.mysql.jdbc.Driver"; // Driver per database mysql
dbLogin = "user"; // Login della base di dati
dbPassword = "psw"; // Password per l'accesso al database
}
// Funzione privata che carica il driver per l'accesso al database.
// In caso di errore durante il caricamento del driver solleva un'eccezione.
private void loadDriver() throws ConnectionPoolException {
try {
java.lang.Class.forName(dbDriver);
}
catch (Exception e) {
throw new ConnectionPoolException();
}
}
public static synchronized ConnectionPool getConnectionPool()
throws ConnectionPoolException {
if(connectionPool == null) {
connectionPool = new ConnectionPool();
}
return connectionPool;
}
// Il metodo getConnection restituisce una connessione libera prelevandola
// dalla coda freeConnections oppure se non ci sono connessioni disponibili
// creandone una nuova con una chiamata a newConnection
public synchronized Connection getConnection() throws ConnectionPoolException {
Connection con;
if(freeConnections.size() > 0) { // Se la coda delle connessioni libere non è vuota
con = (Connection)freeConnections.firstElement(); // Preleva il primo elemento
freeConnections.removeElementAt(0); // e lo cancella dalla coda
try {
if(con.isClosed()) { // Verifica se la connessione non è più valida
con = getConnection(); // Richiama getConnection ricorsivamente
}
}
catch(SQLException e) { // Se c'è un errore
con = getConnection(); // richiama getConnection ricorsivamente
}
}
else { // se la coda delle connessioni libere è vuota
con = newConnection(); // crea una nuova connessione
}
return con; // restituisce una connessione valida
}
// Il metodo newConnection restituisce una nuova connessione
private Connection newConnection() throws ConnectionPoolException {
Connection con = null;
try {
con = DriverManager.getConnection(dbUrl,dbLogin,dbPassword); // crea la connessione
}
catch(SQLException e) { // in caso di errore
throw new ConnectionPoolException(); // solleva un'eccezione
}
return con; // restituisce la nuova connessione
}
// Il metodo releaseConnection rilascia una connessione inserendola
// nella coda delle connessioni libere
public synchronized void releaseConnection(Connection con) {
freeConnections.add(con); // Inserisce la connessione nella coda
}
}
MA credo che abbia delle limitazioni..
-Come fa a limitare il numero di connessioni.
-Il Timeout??
-Le trnasazioni??
2) usare JNDI ... ma non riesco bene a capire come funziona per ora.. :Prrr:
http://tomcat.apache.org/tomcat-5.5-doc/jndi-datasource-examples-howto.html#Introduction
3) ho visto altre librerie in grado di fare un pool i connessioni ma non so bene come si utilizzano..
Se qualconu sa qualcosa o può consigliare ben venga ne sarei grato.. :ave:
isAlreadyInUse
20-11-2007, 08:47
Io ho usato
http://homepages.nildram.co.uk/~slink/java/DBPool/
e per le mie webbapp uso JNDI sfruttando tomcat per il pool di connessioni, e mi sembra la soluzione piu adatta.... se vedi la documentazione di tomcat c'è tutto segnato passo passo.
Io ho usato
http://homepages.nildram.co.uk/~slink/java/DBPool/
e per le mie webbapp uso JNDI sfruttando tomcat per il pool di connessioni, e mi sembra la soluzione piu adatta.... se vedi la documentazione di tomcat c'è tutto segnato passo passo.
bene bene, ho proprio un problemino con tomcat + jndi :D
nel file context ho configurato risorsa e parametri:
<Resource name="jdbc/mioDB" auth="Container" type="javax.sql.DataSource" />
<ResourceParams name="jdbc/mioDB">
...
</ResourceParams>
nel web.xml ho referenziato la risorsa:
<resource-ref>
...
</resource-ref>
quando vado a fare il lookup del datasource, me lo trova ma quando provo a chiedergli gentilmente una connessione, sto stronzo mi risponde con questa eccezione:
Cannot create JDBC driver of class '' for connect URL 'null'
il fatto che non riesca a trovare la classe del driver e l'url del db, mi sembra un po' strano visto che sono nello stesso file di configurazione dove è dichiarata la risorsa (il datasource) che viene invece trovata.
girando un po' per la rete mi sono imbattuto in diverse persone che hanno lo stesso problema e c'è chi ha risolto dichiarando risorsa e parametri nel server.xml e linkando la risorsa nel context.xml, chi rinominando il context.xml in %contestoApp%.xml e mettendolo nella cartella META-INF.
inutile dire che ho provato pure io, non ottenendo risultati.
mi sono accorto però che mancavano le librerie commons-dbcp e commons-pool e cercando un po le ho trovate nel sito di jakarta.
scaricate ed aggiunte non sono servite a nulla, se non a peggiorare la situazione in quanto il lookup della risorsa che prima andava a buon fine con quelle librerie restituiva null.
consigli? :stordita:
isAlreadyInUse
20-11-2007, 10:24
Il connector per il db deve essere il common/lib di tomcat e solo li
Io ho usato
http://homepages.nildram.co.uk/~slink/java/DBPool/
e per le mie webbapp uso JNDI sfruttando tomcat per il pool di connessioni, e mi sembra la soluzione piu adatta.... se vedi la documentazione di tomcat c'è tutto segnato passo passo.
:ave: Grazie mille :ave:
queste librerie sono fantastiche..
:D
ma sorge ancora un piccolo problema..
Quando faccio
ConnectionPoolManager cpm = ConnectionPoolManager.getInstance("../db.properties");
// creo una connessione del Pool
Connection con = cpm.getConnection("intr");
dopo la connessione "con" la devo chiudere oppure no.. insomma devo fare
con.close();
oppure esiste qualche altro modo..
o addirittura non serve..
:D :D
isAlreadyInUse
20-11-2007, 10:42
Leggi la documentazione, se non erro ci sta scritto che te le devi chiudere.
Leggi la documentazione, se non erro ci sta scritto che te le devi chiudere.
Grazie grazie grazie grazie... :ave: ave:
Ti sono debitore... :D:D:D
isAlreadyInUse
20-11-2007, 10:47
Ok mi devi un caffè
Il connector per il db deve essere il common/lib di tomcat e solo li
il connector era nella directory WEB-INF/lib/ dell'applicazione...
...l'ho spostato in %CATALINA_HOME%/common/lib/.
risultato? ...sempre la stessa eccezione :mc:
edit: ho forse male interpretato il tuo consiglio?
Ok mi devi un caffè
te ne pago 10
io ho fatto questa classe per il
public class ConnManager {
private ConnManager() {}
public static synchronized Connection getConnect() throws IOException, SQLException
{
ConnectionPoolManager cpm = null;
cpm = ConnectionPoolManager.getInstance("../db.properties");
return cpm.getConnection("intr");
}
}
ERRORE
exception
org.apache.jasper.JasperException
org.apache.jasper.servlet.JspServletWrapper.handleJspException(JspServletWrapper.java:510)
org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:375)
org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:314)
org.apache.jasper.servlet.JspServlet.service(JspServlet.java:264)
javax.servlet.http.HttpServlet.service(HttpServlet.java:802)
org.netbeans.modules.web.monitor.server.MonitorFilter.doFilter(MonitorFilter.java:368)
root cause
javax.servlet.ServletException
org.apache.jasper.runtime.PageContextImpl.doHandlePageException(PageContextImpl.java:858)
org.apache.jasper.runtime.PageContextImpl.handlePageException(PageContextImpl.java:791)
org.apache.jsp.admin2.ctrl_jsp._jspService(ctrl_jsp.java:92)
org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:97)
javax.servlet.http.HttpServlet.service(HttpServlet.java:802)
org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:332)
org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:314)
org.apache.jasper.servlet.JspServlet.service(JspServlet.java:264)
javax.servlet.http.HttpServlet.service(HttpServlet.java:802)
org.netbeans.modules.web.monitor.server.MonitorFilter.doFilter(MonitorFilter.java:368)
root cause
java.sql.SQLException
snaq.db.ConnectionPool.getConnection(ConnectionPool.java:222)
snaq.db.ConnectionPoolManager.getConnection(ConnectionPoolManager.java:571)
conn.ConnManager.getConnect(ConnManager.java:26)
DB.UtenteApp.UtenteDAO.loadByUsername(UtenteDAO.java:139)
DB.UtenteApp.Utente.leggiDatidaDB_LOGIN(Utente.java:297)
org.apache.jsp.admin2.ctrl_jsp._jspService(ctrl_jsp.java:72)
org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:97)
javax.servlet.http.HttpServlet.service(HttpServlet.java:802)
org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:332)
org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:314)
org.apache.jasper.servlet.JspServlet.service(JspServlet.java:264)
javax.servlet.http.HttpServlet.service(HttpServlet.java:802)
org.netbeans.modules.web.monitor.server.MonitorFilter.doFilter(MonitorFilter.java:368)
Il file e properties è presente nella cartella WEB-INF
cosi strutturato
drivers=com.mysql.jdbc.Driver
logfile=dbpool.log
intr.url=jdbc:mysql://127.0.0.1:3306/intr
intr.user=root
intr.password=null
intr.maxpool=5
intr.maxconn=10
intr.expiry=30
intr.init=5
intr.validator=snaq.db.AutoCommitValidator
intr.cache=true
intr.debug=false
isAlreadyInUse
20-11-2007, 12:16
Mi sa che cosi non lo raggiungi il file
il connector era nella directory WEB-INF/lib/ dell'applicazione...
...l'ho spostato in %CATALINA_HOME%/common/lib/.
risultato? ...sempre la stessa eccezione :mc:
edit: ho forse male interpretato il tuo consiglio?
tadaaaaaaaaaaaan risolto!
prima avevo dichiarato la risorsa e poi avevo specificato i parametri in questo modo:
<Resource name="jdbc/mioDB" auth="Container" type="javax.sql.DataSource" />
<ResourceParams name="jdbc/mioDB">
...
</ResourceParams>
non so come mi sia venuto in mente di provare in questo:
<Resource name="jdbc/mioDB" auth="Container" type="javax.sql.DataSource"
nomeParametro="valoreParametro" ... />
e così funzica tutto ^^
'iao
isAlreadyInUse
21-11-2007, 18:03
Infatti anche io faccio nel secondo modo come da documentazione Tomcat :D
infatti io da povero degenerato avevo guardato la documentazione del 4 piuttosto di quella del 5.5 :sofico:
vBulletin® v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.