Como crear un pool de conexiones en Tomcat

Vamos a ver un ejemplo de como crear un pool de conexiones con el servidor Apache Tomcat en una aplicación Java EE.

Usar un pool de conexiones es más eficiente que abrir una nueva conexión cada vez que sea necesario por lo tanto no hay motivo para no usar un pool de conexiones, vamos a ver como como configurar un pool de conexiones en Tomcat.

El primer paso es editar el archivo context.xml del Tomcat (/conf/context.xml) y añadir el datasource para después poder recuperarlo desde java con JNDI.


<Context>
    <Resource name="jdbc/ConexionMySQL" auth="Container" type="javax.sql.DataSource"
        maxActive="20" maxIdle="10" maxWait="5000"
        username="usuarioBD" password="passwordBD" driverClassName="com.mysql.jdbc.Driver"
        url="jdbc:mysql://localhost:3306/tuBaseDeDatos"/>

</Context>

Vamos a ver que significan los parámetros que hemos usado, si quieres ver todos los posibles aqui tienes la lista completa en ingles.

  • maxActive: Indica el número máximo de conexiones que pueden estar abiertas al mismo tiempo.
  • maxIdle: El numero máximo de conexiones inactivas que permanecerán abiertas, si el numero de conexiones inactivas es muy bajo puede darse el caso de que las conexiones se cierren porque se llega al máximo de conexiones inactivas y se vuelvan a abrir inmediatamente reduciendo la eficiencia ya que se perdería la ventaja del uso de pool de conexiones en cuanto a que no hay que abrir una conexión cada vez que es necesario.
  • maxWait: Es el tiempo máximo (en ms) que se esperará a que haya una conexión disponible (inactiva), si se supera este tiempo se lanza una excepción.
  • username: Usuario de la base de datos.
  • password: Password para el usuario introducido en username.
  • driverClassName: Nombre del driver JDBC para conectar con la base de datos.
  • url: URL de la base de datos a la que nos queremos conectar.

Si ${catalina.base} es distinto de ${catalina.home} el archivo que tienes que editar es ${catalina.base}/conf/context.xml, si por ejemplo usas NetBeans te encontraras en este caso (Puedes ver la ruta a la que apunta catalin.base en las propiedades del Tomcat haciendo click derecho sobre el servidor. ) y el archivo context.xml no existe por lo que lo tendrás que crear o copiar de la carpeta de instalación del Tomcat.

Ahora hay que añadir el recurso creado en el descriptor de despliegue de nuestra aplicación (WEB-INF/web.xml).


<resource-ref>
    <description>Pool conexiones MySQL</description>
    <res-ref-name>jdbc/ConexionMySQL</res-ref-name>
    <res-type>javax.sql.DataSource</res-type>
    <res-auth>Container</res-auth>
</resource-ref>

Con estos pasos ya tenemos el pool listo para poder ser usado en nuestras aplicación ya solo queda incluir la librería del driver JDBC correspondiente en ${catalina.home}/lib/ o incluirla en la aplicación, en la documentación pone que hay que incluirla en la carpeta del Tomcat pero si la pones en la aplicación también funciona.

Y para terminar un ejemplo de uso del pool de conexiones usado, que no tiene demasiado que explicar pues la diferencia de usar el pool o no esta en que si no se hace la conexión se obtiene desde DriverManager y en este caso se hace desde el DataSource que obtenemos haciendo lookup sobre InitialContext pasándole el nombre del DataSource que hemos creado, precedido de «java:/comp/env/». Y una vez obtenida la conexión todo es igual pero hay que asegurarse de cerrar el ResulSet y el Statement porque aunque se «cierre» la conexión en realidad lo que ocurre es que se devuelve al pool por lo que hay que cerrarlos manualmente porque el ResulSet y el Statement se cierran automáticamente si se cierra la conexión pero en un pool las conexiones no se cierran (bueno, si el numero de conexiones inactivas es mayor que el indicado en maxIdle si se cierran). Y finalmente devolver la conexión al pool para que pueda ser reutilizada.


Context initContext;
Connection cn = null;
Statement st = null;
ResultSet rs = null;

try {
    initContext = new InitialContext();
    DataSource ds = (DataSource) initContext.lookup("java:/comp/env/jdbc/ConexionMySQL");
    cn = ds.getConnection();

    String sqlBusqueda = "SELECT nombre, apellido FROM clientes";
    st = cn.createStatement();
    rs = st.executeQuery(sqlBusqueda);

    while (rs.next()) {
        out.println("Nombre: " + rs.getString("nombre") + "
"); out.println("Apellido: " + rs.getString("apellido") + "
"); } } catch (SQLException ex) { log.error("Error (" + ex.getErrorCode() + "): " + ex.getMessage()); } catch (NamingException ex) { log.error("Error al intentar obtener el DataSource: " + ex.getMessage()); } finally { if (rs != null) { try { rs.close(); } catch (SQLException ex) { log.error("Error (" + ex.getErrorCode() + "): " + ex.getMessage()); } } if (st != null) { try { st.close(); } catch (SQLException ex) { log.error("Error (" + ex.getErrorCode() + "): " + ex.getMessage()); } } if (cn != null) { try { cn.close(); } catch (SQLException ex) { log.error("Error (" + ex.getErrorCode() + "): " + ex.getMessage()); } } }

También se puede usar el pool de conexiones desde una pagina JSP si pasas del MVC.


<sql:query var="clientes" dataSource="jdbc/ConexionMySQL">
    SELECT nombre, apellido FROM clientes
</sql:query>
        
<c:forEach var="cliente" items="${clientes.rows}">
    Nombre: ${cliente.cantidad} <br />
    Apellido: ${cliente.tipo} <br />
</c:forEach>   

Aquí puedes descargar el proyecto de ejemplo (el archivo context.xml esta incluido en el rar).

6 Comments

  1. JuanMa 14 agosto, 2013 Reply
    • Iván Salas 26 agosto, 2013 Reply
  2. zi 4 febrero, 2014 Reply
    • daniel 19 febrero, 2015 Reply
  3. Carina Ripoll Pérez 17 noviembre, 2017 Reply
    • Iván Salas 17 noviembre, 2017 Reply

Leave a Reply