Pool de Conexoes JDBC Oracle

Pessoal,

Estou tentando implementar um pool de conexoes para uma base oracle, mas para cada requisicao, em vez de aproveitar as conexoes abertas ele cria novas conexoes. Segue abaixo meu codigo:

import java.sql.SQLException;
import java.util.Properties;
import org.apache.log4j.Logger;
import oracle.jdbc.pool.OracleConnectionCacheImpl;
import oracle.jdbc.pool.OracleConnectionPoolDataSource;

public class PoolConexaoSingleton {
	
	public static PoolConexaoSingleton instance;
	
	private OracleConnectionPoolDataSource ocpds = null;
	private OracleConnectionCacheImpl ods = null;
	private static Logger logger = Logger.getLogger(Utilitarios.class);
	private Utilitarios objUtil  = new Utilitarios();
	private Properties appProps  = objUtil.carregaPropriedades(); 
	
	private PoolConexaoSingleton(String tpAmb){
		try{
			
		String ip   = appProps.getProperty(ip);
	    	String port = appProps.getProperty(port);
	    	String sid  = appProps.getProperty(sid);
	    	String user = appProps.getProperty(user);
	    	String pass = appProps.getProperty(pass);
	    	
						 
		ocpds = new OracleConnectionPoolDataSource();
		ocpds.setURL("jdbc:oracle:thin:@" + ip + ":" + port + ":" + sid);

		ocpds.setUser(user);
		ocpds.setPassword(pass);
			
		ods = new OracleConnectionCacheImpl(ocpds);
		ods.setMinLimit(10);
		ods.setMaxLimit(30);
		ods.setCacheScheme(OracleConnectionCacheImpl.FIXED_WAIT_SCHEME); 
			    	
    	}catch(SQLException se){
    		logger.info("Exception PoolConexaoSiebel -> [" + se.getMessage() + "]");
    	}
	}
		
	public static PoolConexaoSingleton getInstance(String tpAmb){
		
		if (instance == null)
			instance = new PoolConexaoSiebelSingleton(tpAmb);
		
		return instance;
		
	}
		
	public OracleConnectionCacheImpl getOracleConnectionCacheImpl(){
		return this.ods;
	}
	
	public OracleConnectionPoolDataSource getOracleConnectionPoolDataSource(){
		return this.ocpds;
	}

}

Classe que chema o singleton

import java.sql.CallableStatement;
import java.sql.Connection;
import java.util.Properties;
import oracle.jdbc.driver.OracleTypes;
import org.apache.log4j.Logger;
import br.com.alcatellucent.gvpws.lib.PoolConexaoSiebelSingleton;
import br.com.alcatellucent.gvpws.lib.Utilitarios;
import br.com.alcatellucent.gvpws.lib.XmlHandler;

public class WsApi043 {
	
	private Utilitarios objUtil  = new Utilitarios();
    private static Logger logger = Logger.getLogger(Utilitarios.class);
    private Properties appProps  = objUtil.carregaPropriedades(); 
    private String resposta = "02;";
    private String status = "";
    private String msisdn = "";
    private String[][] matRetorno = new String[1][2];
    private String xmlRetorno = "";
    private int timeOut = 26000;
    private Connection conn = null;
    private String idRequisicao = "";
    private String processo = "";
           
   
	
    public String executarTransacao(String tpAmb, String dadosEntrada, String timeout){
   	         
        try
        {        
          this.timeOut = Integer.parseInt(timeout); 
        }
        catch (Exception ex)
        {
          this.timeOut = 26000;
        }
        
        // Realizando parse do XML de entrada para obter indentificador_requisicao e processo
        // Estes valores serão utilizados na inserção do novo registro
        XmlHandler xmlFields = new XmlHandler(dadosEntrada, true);
        if(xmlFields.ready()){
      	   this.msisdn = xmlFields.get("m");
      	   this.idRequisicao = xmlFields.get("identificador_requisicao");     
           this.processo = xmlFields.get("processo");	
        }else 
           logger.error("ID de Requisicao e(ou) Processo nao foi encontrado no xml de entrada.");
                
        try{
        	
        	conn = PoolConexaoSingleton.getInstance(tpAmb).getOracleConnectionCacheImpl().getConnection();
        	logger.info("Connection Instance -> [" + conn.toString() + "]");
        	CallableStatement cs = conn.prepareCall("{call pkg.prc_principal (?, ?)}");
        	cs.setString(1, this.campo);
            cs.registerOutParameter(2, OracleTypes.VARCHAR);
            cs.execute();
           
            
            if (cs.getString(2) != null && !cs.getString(2).trim().equals("")){
            	this.resposta = "00;";
            	this.status = cs.getString(2);
            }
            
            cs.close();
            
            
         
            
        }catch(Exception se){
        	logger.info("Exception -> [" + se.getMessage() + "]");
        	this.resposta += se.getMessage();
        }
        
        //Matriz fonte para montar XML de retorno para URA     
        matRetorno[0][0] = "STATUS";
        matRetorno[0][1] = this.status;
        
        //Cria um XML em formato string através da matriz fonte
        try{
			xmlRetorno = xmlFields.Build(matRetorno);
		}catch(Exception e){
			logger.info("Erro criar xml -> [" + e.getMessage() + "]");
		}
        		
        resposta += xmlRetorno;
        
        try{
        	
        	//if (conn != null)
        	//	conn.close();
        	
        }catch(Exception ex1){
        	logger.info("Exception ao desconectar -> [" + ex1.getMessage() + "]");
        	resposta += ex1.getMessage();
        }
        
        xmlFields = null;   
        
        
        
        return resposta;     
    } 

}

Se alguem já passou por isso e puder me ajudar agradeço.

Você não quer usar um pool pronto, como o C3PO ou o DBCP?

Saiba que há vários detalhes que devem ser seguidos para fazer um pool funcionar direito. Por exemplo, você precisa se preocupar com conexões que ficaram um tempo ociosas - normalmente o banco acaba fechando essas conexões automaticamente, e então você acaba ficando com um mico na mão, que é uma conexão do pool que está inválida. Esse tipo de detalhes o C3PO já deve tomar conta.

Esses pools normalmente têm métodos para você pegar a “conexão subjacente” (underlying connection) que é a OracleConnection, por exemplo, para você poder chamar os métodos que não existem na java.sql.Connection normal.

Cara,

Obrigado pela resposta…implementei uma solucao usando DBCP, mas estou com uns problemas, vamos ver se alguem pode me ajudar, segue abaixo meu codigo.

[code]import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Properties;

import org.apache.commons.dbcp.BasicDataSource;
import org.apache.log4j.Logger;

public class Dbcp {

private static Dbcp instance = null; 
private DataSource ds; 
private static int maxConnections; 
private static long maxWait; 
private static Logger logger = Logger.getLogger(Utilitarios.class);
private Utilitarios objUtil  = new Utilitarios();
private Properties appProps  = objUtil.carregaPropriedades(); 
private static String ip = "";
private static String port = "";
private static String sid = "";
private static String user = "";
private static String pass = "";
		
public static Dbcp getInstance(String tpAmb) { 
	if(instance == null) { 
		instance = new Dbcp(tpAmb); 
		
	} 
	return instance; 
} 

public Dbcp(String tpAmb){
	ip   = appProps.getProperty("s.ip."+ tpAmb);
	port = appProps.getProperty("s.port."+ tpAmb);
	sid  = appProps.getProperty("s.sid."+ tpAmb);
	user = appProps.getProperty("s.user."+ tpAmb);
	pass = appProps.getProperty("s.pass."+ tpAmb);
	maxConnections = 10;
	maxWait = 10000L;
	ds = setupDataSource(); 
}

public static DataSource setupDataSource() {
	
	
    BasicDataSource ds = new BasicDataSource();
    ds.setDriverClassName("oracle.jdbc.driver.OracleDriver"); 
    ds.setUsername(user); 
    ds.setPassword(pass); 
    ds.setUrl("jdbc:oracle:thin:@" + ip + ":" + port + ":" + sid); 
    ds.setInitialSize(10);
    ds.setMaxActive(maxConnections); 
    ds.setMaxWait(maxWait); 
    ds.setMaxIdle(1);
    ds.setDefaultAutoCommit(true);
    ds.setRemoveAbandoned(true);
    ds.setRemoveAbandonedTimeout(3000);
    
           
    return ds; 
}

public void printDataSourceStats() throws SQLException {
    BasicDataSource bds = (BasicDataSource) ds;
    logger.info("Num Active Connections: " + bds.getNumActive());
    logger.info("NumIdle: " + bds.getNumIdle());
}

public Connection getConn() throws SQLException { 
	return ds.getConnection(); 
} 

public void shutdownDataSource() throws SQLException {
    BasicDataSource bds = (BasicDataSource) ds;
    bds.close();
}

}
[/code]

Crio a conexao na outra classe que chama o metodo getConn, o problema eh que ao inves de quando dou um close() na conexao ele nao volta para o pool, ele simplemente fecha a conn e a abre outra ao inves de aproveitar as conexoes que estao sendo gerenciadas pelo pool.