Connection Pool

Estou usando um exemplo de uma classe que usa Connection Pool que achei em um livro para fazer várias conexões ao banco:

import java.util.;
import java.sql.
;

public class PoolConexao

{
private Hashtable connections = new Hashtable();
private Properties props;

public PoolConexao (Properties props, int conexaoinicial)
throws SQLException, ClassNotFoundException
{

   this.props = props;
   initializePool(props, conexaoinicial);

}

public PoolConexao (String driverClassname, String dbUrl, String user, String password,int conexaoinicial)
throws SQLException, ClassNotFoundException
{
props = new Properties();
props.put(“connection.driver”,driverClassname);
props.put(“connection.url”,dbUrl);
props.put(“user”,user);
props.put(“password”,password);
initializePool(props,conexaoinicial);
}

public Connection getConnection() throws SQLException
{
Connection con = null;
Enumeration cons = connections.keys();
synchronized (connections) {
while (cons.hasMoreElements()) {
con = (Connection)cons.nextElement();
Boolean b = (Boolean)connections.get(con);
if (b == Boolean.FALSE)
{
try
{
con.setAutoCommit(true);
}
catch (SQLException e)
{
connections.remove(con);
con = getNewConnection();
}
connections.put(con,Boolean.TRUE);
System.out.println(“conectou - 1”);
return con;
}
}
con = getNewConnection();
connections.put(con, Boolean.FALSE);
System.out.println(“conectou - 2”);
return con;
}
}

public void returnConnection(Connection returned)
{
if (connections.containsKey(returned))
connections.put(returned, Boolean.FALSE);
}

private void initializePool(Properties props,int conexaoinicial)
throws SQLException, ClassNotFoundException
{
Class.forName(props.getProperty(“connection.driver”));
for (int i = 0; i < conexaoinicial; i++)
{
Connection con = getNewConnection();
connections.put(con, Boolean.FALSE);
}
}

private Connection getNewConnection()
throws SQLException
{
return DriverManager.getConnection(props.getProperty(“connection.url”),props);
}
}

e coloquei na minha servlet:

import java.io.;
import javax.servlet.
;
import javax.servlet.http.;
import java.sql.
;
import java.util.*;

public class ConsultaCandidato extends HttpServlet
{
private PoolConexao pool;

   public void init(ServletConfig servletConfig)
	throws ServletException
{
     String jdbcDriver = "interbase.interclient.Driver";
 String jdbcSubProtocol = "jdbc:interbase://localhost/";
     String dbName = "c:/monografia/eleicao.gdb";
     String dbUser = "SYSDBA";
     String dbPasswd = "masterkey";
     try
        {
           pool = new PoolConexao(jdbcDriver,jdbcSubProtocol + dbName,dbUser, dbPasswd,5);
           System.out.println("Banco conectado !");

        }
     catch (Exception e)
        {
          System.out.println("Banco não conectado !!");
        }
}

public void doPost(HttpServletRequest request, HttpServletResponse response)
	throws ServletException, IOException
{
	Connection con = null;
            Statement statement = null;
            try
	{  
               con = pool.getConnection();
               con.setAutoCommit(false); 
               contador = 0; 
               statement = con.createStatement();

Mas não estou conseguindo me conectar ao banco. Onde está o erro ?

Cara, se você não consegue se conectar podem ser vários os problemas, desde a sua string de conexão até o seu mdb não existir.

Aqui vão 2 dicas importantes:

  • quando há um erro, a primeira coisa a postar é a mensagem que você recebe da aplicação; gigantesca maioria dos problemas podem ser resolvidos ao decodificar a exceção que está ocorrendo
  • se mesmo assim achar que é necessário postar o seu código, tente resumi-lo à parte onde está o erro e use as tags [ code]seucodigo[ /code], assim ele fica endentado :wink:

Pelo que vi em seu código…eu uso a mesma classe de Pool que vc está usando, porém com algumas modificações. Para se fazer um pool nesses moldes, vc usa o padrão singleton. Os construtores de sua classe não devem ser públicos, devem ser PRIVADOS(private), de forma que vc só consiga instancia a classe ConnectionPool de dentro da própria classe através de um métodos público(public).
Ficou mais ou menos assim:

private ConnectionPool&#40;&#41; &#123;
    this.props = props;
    try &#123;
      
    	// lê o arquivo db.properties
		InputStream is = getClass&#40;&#41;.getResourceAsStream&#40;&quot;/db.properties&quot;&#41;;
		props = new Properties&#40;&#41;;        
	    // carrega o arquivo na variável de propriedades
	    props.load&#40;is&#41;;
      
    	initializePool&#40;props&#41;; 
      	
    &#125;
    catch&#40; ClassNotFoundException se &#41; &#123;
      System.err.println&#40; &quot;PoolConnections.Constructor&#40;&#41;.ClassNotFoundException&#58; &quot; + se.getMessage&#40;&#41; &#41;;
    &#125;
    catch&#40; SQLException se &#41; &#123;
      System.err.println&#40; &quot;PoolConnections.Constructor&#40;&#41;.SQLException&#58; &quot; + se.getMessage&#40;&#41; &#41;;      
      se.printStackTrace&#40;&#41;;
    &#125;
     catch&#40; IOException se &#41; &#123;
      System.err.println&#40; &quot;PoolConnections.Constructor&#40;&#41;.IOException&#58; &quot; + se.getMessage&#40;&#41; &#41;;      
      se.printStackTrace&#40;&#41;;
    &#125;
  &#125;

…e o método que retorna a instância

public static ConnectionPool getPool&#40;&#41;&#123;
  	
  	//Se o pool ainda não foi criado
  	if &#40; pool == null &#41;&#123;  		
        
        pool = new ConnectionPool&#40;&#41;;
        data = Data.getDateTime&#40;&#41;;
        contador = 0;
  	&#125;
								 
  	return pool;
  &#125;

Estou conseguindo conectar e usar sem problemas…

Sendo chato: pra que implementar um pool, se tem zilhoes de implementacoes opensource por ai, como o commons-dbcp, por exemplo, e se todo application server que se preze tem um pool incluso? :?

O problema é o seguinte: estou usando servlets para fazer conexão a um banco Interbase. Um servlet chama outro servlet e cada servlet que eu chamo acabo fazendo mais uma conexão ao banco. Porém depois de um certo número de conexões, elas ultrapassam o limite do banco e dá erro.
Pergunta: Como posso fazer para que eu faça apenas uma conexão ao banco (na primeira vez uma servlet é chamada) e depois continuo com a mesma conexão aberta, para todas as outras servlets, sem que eu precise fazer uma conexão novamente. :frowning:

Se voce usar o Pattern de BusinessDelegate ou de SessionFacade (depende do caso) voce evitaria esse problemas… Pois uma requisicao HTTP nao importando por quantos Servlets, JSPs ou TagLibs passasse, seria essa camada que controlaria as conexoes, bem como COMMIT e ROLLBACK das transacoes…

Se o volume de usuario concorrentes, fazendo transacoes, execeder as conexoes do banco, entao vou pode optar por um Pool de Conexoes, e de preferia do Application Server que voce esteja usando…

Boa sorte.