Aumenta el rendimiento de tus tests de integración con BBDD usando un pool de conexiones dbcp2 con BasicDataSource de Apache

Pasa tus tests de integración con base de datos a la velocidad de la luz con dbcp2 BasicDataSource. Si estás utilizando para conectar a la base de datos DriverManagerDataSource de Spring JDBC estás perdiendo tiempo y recursos de forma exponencial.

Índice de contenidos


1. Introducción

Puede que «Han Solo» haya recorrido el «Corredor Kessel» en menos de 12 segundos, pero nadie será más rápido que tú ejecutando los tests de integración contra la base de datos si sigues los pasos de este tutorial.


2. Entorno

El tutorial está escrito usando el siguiente entorno:

  • Hardware: Portátil MacBook Pro Retina 15′ (2.3 Ghz Intel Core I7, 16GB DDR3).
  • Sistema Operativo: Mac OS Sierra 10.12.5
  • Entorno de desarrollo: Eclipse Oxygen
  • Apache Maven 3.3.0
  • Java 8
  • Spring 4


3. DriverManagerDataSource de Spring JDBC

Es muy posible que hasta ahora usaras una clasecita que tienen en Spring JDBC (DriverManagerDataSource.java), muy utilizada por verse en muchos ejemplos de Internet, para conectar con tu base de datos, y ejecutar tus tests de integración, donde pruebas todas tus querys de forma transaccional para que no dependan unos tests de otros. Seguramente tus contextos de tests de Spring tengan una pinta parecida a lo siguiente:

applicationContext-test.xml
	<bean name="dataSource"
		class="org.springframework.jdbc.datasource.DriverManagerDataSource">
		<property name="driverClassName" value="oracle.jdbc.driver.OracleDriver"></property>
		<property name="url"
			value="jdbc:oracle:thin:@IP:PUERTO:NOMBRE_BBDD"></property>
		<property name="username" value="Chewbacca"></property>
		<property name="password" value="MUGRUUUUUUUHMA"></property>
	</bean>

Esta es una de las formas más usadas. El problema viene cuando empiezas a leer como funciona lo que estás usando. Os copio una imagen del javadoc.

Básicamente dice que esta clase no utiliza un pool de conexiones, y que si quieres usar un pool puedes usar alternativas, de hecho te proponen la que te voy a contar en este tutorial.


4. dbcp2 BasicDataSource de Apache

¿Y para que quiero yo un pool de conexiones en los tests?

Pues para lo mismo que en producción. Los tests, lo que hacen, cada uno de ellos que ejecuta una consulta en BBDD es lo siguiente. Abro conexión, hago cosas, cierro conexión. Y hacen eso por cada test, de forma secuencial. Es decir, que por cada test, estás abriendo y cerrando conexión. Esta operación es una operación muy costosa para la BBDD, y bases de datos tan populares y usadas como Oracle pueden tardar segundos (1-2 segundos) en crear una conexión nueva, con el consiguiente uso de CPU. Todo ello para ejecutar una query, que muy probablemente dure 0.001 segundos.

La solución es utilizar un pool de conexiones de tal forma que cuando un test termina, libera la conexión, que vuelve al pool, y el siguiente test la reusa, con lo que no gasta tiempo en abrir una conexión nueva. Mira lo fácil que es hacer el cambio.

applicationContext-test.xml
	<bean name="dataSource" class="org.apache.commons.dbcp2.BasicDataSource"
		destroy-method="close">
		<property name="url"
			value="jdbc:oracle:thin:@IP:PUERTO:NOMBRE_BBDD" />
		<property name="driverClassName" value="oracle.jdbc.driver.OracleDriver" />
		<property name="username" value="OBIWAN" />
		<property name="password" value="USETHEPOOLLUKE" />
		<property name="removeAbandonedOnMaintenance" value="true" />
		<property name="initialSize" value="1" />
		<property name="maxTotal" value="15" />
	</bean>

Además te recomiendo que como los tests se ejecutan en orden secuencial, de 1 en 1, no te vuelvas loco creando conexiones a la BBDD de inicio. Con 1, para la mayoría de casos es suficiente, y te ahorras esos segundos de reutilizar otras conexiones que nunca vas a usar. Por eso pongo initialSize a 1.

Para poder utilizar esa clase, solo tienes que añadir a tu pom.xml de maven la siguiente dependencia.

applicationContext-test.xml
	<!-- https://mvnrepository.com/artifact/org.apache.commons/commons-dbcp2 -->
	<dependency>
		<groupId>org.apache.commons</groupId>
		<artifactId>commons-dbcp2</artifactId>
		<version>2.1.1</version>
		<scope>test</scope>
	</dependency>


5. Conclusiones

Si haces TDD como nosotros en Autentia, vas a acabar con muchos tests. Algunos de esos serán de integración. En nuestro caso, en proyectos grandes podemos llegar a varios miles de tests de integración. Si por cada uno de ellos gastáramos 1 segundo en crear la conexión estaríamos horas esperando a que se terminaran, y no sería efectivo el pasarlos, ni la integración continua en Jenkins. Con este cambio conseguimos pasar esos miles de tests de integración en un par de minutos. Espero que te haya servido este tutorial, y que eleves el rendimiento de tus tests a la enésima potencia.

Comentarios

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

He leído y acepto la política de privacidad

Información básica acerca de la protección de datos

  • Responsable: IZERTIS S.A.
  • Finalidad: Envío información de carácter administrativa, técnica, organizativa y/o comercial sobre los productos y servicios sobre los que se nos consulta.
  • Legitimación: Consentimiento del interesado
  • Destinatarios: Otras empresas del Grupo IZERTIS. Encargados del tratamiento.
  • Derechos: Acceso, rectificación, supresión, cancelación, limitación y portabilidad de los datos.
  • Más información: Puedes ampliar información acerca de la protección de datos en el siguiente enlace:política de privacidad

Consultor tecnológico de desarrollo de proyectos informáticos.
Ingeniero técnico en informática de gestión y graduado en ingeniería del software por la Universidad Politécnica de Madrid.
Puedes encontrarme en Autentia: Ofrecemos servicios de soporte a desarrollo, factoría y formación.
Somos expertos en Java/Java EE

¿Quieres publicar en Adictos al trabajo?

Te puede interesar

10/06/2025

Iván Suarez Romero

Aprende cómo migrar tu sitio Joomla 3 a Joomla 5 de forma segura, manteniendo el diseño, la funcionalidad y compatibilidad con extensiones. Una guía paso a paso con recomendaciones, imágenes y buenas prácticas para actualizar sin sorpresas.

04/06/2025

Gonzalo Matarrubia González

Descubre qué es Yocto Project, sus ventajas, usos reales en Izertis y cómo crear tu propia distribución Linux para Raspberry Pi paso a paso, de forma sencilla y flexible.

30/05/2025

Roberto José

¿Trabajas con Drupal y SonarQube 9.9? En este artículo exploramos cómo adaptar el análisis estático para evitar falsos positivos, desactivar reglas conflictivas del Quality Profile y delegar el estilo a PHP CodeSniffer. Una guía práctica para mejorar la integración sin depender aún de SonarQube 10.