Pool de Conexoes JDBC Oracle

2 respostas
F

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.

2 Respostas

T

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.

F

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.

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();
    }
    
    
}

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.

Criado 23 de julho de 2009
Ultima resposta 30 de jul. de 2009
Respostas 2
Participantes 2