PDA

View Full Version : [Java] Pool di connessioni JDBC


Unrue
02-05-2007, 16:10
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?

Unrue
10-05-2007, 18:09
Dai ragazzi, nessuno usa pool di connessioni?

Dix 3
20-11-2007, 08:40
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.

0rph3n
20-11-2007, 10:13
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

Dix 3
20-11-2007, 10:41
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.

Dix 3
20-11-2007, 10:46
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è

0rph3n
20-11-2007, 11:42
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?

Dix 3
20-11-2007, 11:45
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)

Dix 3
20-11-2007, 11:47
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

0rph3n
21-11-2007, 17:52
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

0rph3n
22-11-2007, 08:22
infatti io da povero degenerato avevo guardato la documentazione del 4 piuttosto di quella del 5.5 :sofico: