quarta-feira, 11 de dezembro de 2013

DBCP – Database connection pool



DBCP – Database connection pool

Imagine a seguinte a situação: em uma aplicação sem um pool, caso você abra uma conexão com um banco de dados,  será criado um objeto do tipo Connection na memória,  esse objeto se comunicará com o  seu servidor de banco de dados, e este por sua vez, alocará recursos de instância de forma dedicada para aquela conexão, repetindo-se, cada vez que sua aplicação for iniciada por qualquer usuário(ver figura 01). Esse processo apesar de ser perfeitamente funcional e simples, pode implicar em um alto custo  de performance, caso sua aplicação tenha uma alta demanda de usuários e um grande tráfego de dados.   




Figura 01 – Arquitetura de conexão sem pool

Um Pool de conexões almeja exatamente solucionar esse gargalo, pois através dessa técnica, cada sessão de nossa aplicação, consumirá  apenas uma conexão já existe com o banco de dados.
             
Na verdade, essa conexão vai ser criada somente uma vez pela primeira sessão que a consumi-la,  ou quando o servidor como o TomCat for iniciado, assumindo a responsabilidade de gerenciar o ciclo de vida da conexão em vigor e fornece-la da maneira mais dinâmica possível para as aplicações(ver figura 02).        
           

Figura 02 – Arquitetura de  conexão com pool gerenciado pelo TomCat
Pool de conexões por aplicação(Cada aplicação possui um DBCP).



DBCP   Técnica para criaçao e gerenciamento de um pool de conecções que estão prontas para  serem executadas por qualquer thread que necessite.
JNDI    O JNDI (Java Naming and Directory Interface) é a API J2EE que fornece uma interface padrão para localizar usuários, máquinas, objetos, redes e serviços. Por exemplo, você pode utilizar o JNDI para localizar um computador na rede. Pode ser usado também para buscar objetos Java.

1-    Criar arquivo context.xml na pasta META-INF da aplicação (JNDI)

<?xml version="1.0" encoding="UTF-8"?>

<Context path="/jndi">
  <Resource
      auth="Container"
      driverClassName="org.postgresql.Driver"
      maxActive="20"
      maxIdle="10"
      maxWait="-1"
      name="jdbc/db_pool"
      type="javax.sql.DataSource"
      url="jdbc:postgresql://127.0.0.1:5432/enoc?autoReconnect=true"
      autoReconnect="true"
      username="manuka"
      password="manuka"   />
</Context>

Lembrando que essa é uma das formas de configurar um pool de conexões, pois, podemos usar esse mesmo conjunto de tags XML, no arquivo server.xml, disponível na pasta “conf” do servidor TomCat.

auth
Se definido como “Container”,  será passado ao servidor TomCat, o processo de abertura e fechamento da conexão.
driverClassName
Namespace do pacote do driver JDBC específico do banco de dados.
maxActive
                                                 
Número máximo de conexões do DB no pool, onde pode ser especificado “0” para nenhum limite.
maxIdle
Número máximo das conexões inativas.
maxWait

                        
Tempo máximo (em milesegundos) de espera por uma conexão,  se este intervalo de parada for excedido, uma exceção é lançada. Podemos ajustar com   “-1”  para  esperar indefinidamente.
name
Definição do nome em formato de JNDI(Java Naming and Directory Interface), que servirá como forma de acesso ao nosso pool pela nossa aplicação.
type
Tipo da classe dataSource, que implementará um objeto com a conexão que será compartilhada por várias sessões da aplicação.
url
Caminho de acesso ao serviço do banco de dados, lembrando que  cada banco de dados, tem sua forma própria de chamada.
Username e  password
Respectivamente usuário e senha para acessar o servidor de banco de dados.


2-    Criar arquivo web-xml que vai referenciar a JNDI.

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">

    <session-config>
        <session-timeout>30</session-timeout>
    </session-config>

    <resource-ref>        
        <res-ref-name>jdbc/db_pool</res-ref-name>
        <res-type>javax.sql.DataSource</res-type>
        <res-auth>Container</res-auth>
    </resource-ref>

</web-app>

3-    Copiar drive de banco de dados para \[diretório apache]\common\lib
4-    Gerar modulo da camada MODEL de conecção com o DBCP.(JSP ou bean)

<html>
<%@ page import="java.sql.*" %> 
<%@ page import="javax.naming.Context" %> 
<%@ page import="javax.naming.InitialContext" %> 
<%@ page import="javax.naming.NamingException" %> 
<%@ page import="javax.sql.DataSource" %> 
<%@ page import="java.sql.Connection" %> 
<%@ page import="java.sql.DriverManager" %> 
<%@ page import="java.sql.ResultSet" %> 
<%@ page import="java.sql.Statement" %> 
<%@ page import="java.sql.ResultSetMetaData" %> 
<body>
<%
     try   {
            Context initContext = new InitialContext();
            Context envContext = (Context)initContext.lookup("java:/comp/env");                   
            DataSource ds   = (javax.sql.DataSource)envContext.lookup("jdbc/db_pool");
            Connection conn = ds.getConnection();              
            Statement st      = conn.createStatement();
            String    sql        = "select * from cliente";
            ResultSet rs       = st.executeQuery(sql);             
            while (rs.next())
                        out.println(rs.getString("nome")+"<br />");
            }
            catch(Exception e){
            out.println("Erro: "+e.getMessage());}    
 %> </body>
</html>