Spring Dynamic Datasource

1
5863

En este tutorial veremos como utilizar la clase AbstractRoutingDataSource que proporciona spring.

Índice de contenidos

1. Introducción

En este tutorial vamos a ver como utilizar la clase AbstractRoutingDataSource de spring, que se encuentra el módulo de spring-jdbc, esta clase esta disponible desde la versión 2.0.1 de spring.

¿Qué nos proporciona esta clase?

Pues nos permite cambiar de datasource en tiempo de ejecución.

¿Cómo funciona?

Muy fácil esta clase actúa como intermediario, mientras que el datasource «real» se puede determinar de forma dinámica en tiempo de ejecución en base a una clave de búsqueda.

2. Motivación

Debido a la gran demanda de gente preguntando como hacer para poder cambiar de datasource en tiempo de ejecución. Mucha gente ha creado sus propias soluciones, la gente de spring han sacado una solución para este problema.

Este tutorial vamos hacer un pequeño ejemplo que tenemos 2 bases de datos donde guardamos los equipos de fútbol de cada país, mediante un servicio rest que vamos a obtener todos los equipos pasando como parámetro el código del país

3. Entorno

El tutorial está escrito usando el siguiente entorno:

  • Hardware: MacBook Pro 15′ (2.5 GHz Intel Core i7, 16GB DDR3 SDRAM)
  • Sistema Operativo: Mac OS X Yosomite 10.10.5
  • NVIDIA GeForce GT 750M 2048 MB
  • Eclipse Luna 4.4.2
  • Java 1.8
  • Docker 1.9.0
  • Spring Framework 4.1.6.RELEASE
  • Spring MVC 4.1.6.RELEASE
  • Tomcat 8.0.28
  • curl 7.43.0

4. Creación del proyecto

Vamos a crear una proyecto web para exponer nuestro servicio rest, para facilitar el ejemplo vamos a utilizar bases de datos en memoria, en concreto H2 y HSQL

Lo primero es crear un proyecto web con maven y añadimos las dependencias de Spring y Spring MVC, como puede verse a continuación.

pom.xml

Para facilitar el ejemplo solo vamos a ver el código que se refiere a la clase AbstractRoutingDataSource, el resto estará disponible en el zip de descarga.

CountryRoutingDatasource.java

Como vemos solo tenemos que implemetar el método «determineCurrentLookupKey» donde tenemos que devolver la key del map que contiene AbstractRoutingDataSource, en este caso tenemos definido un CountryDbContextHolder que guarda en un ThreadLocal la key que va usar.

Lo siguiente es ver la configuración de la clase CountryRoutingDatasource en fichero de configuración de spring

configuration-spring-datasource.xml

Como vemos al definir el bean de dataSource (CountryRoutingDatasource) le pasamos a la propiedad targetDataSources que es un map que contiene todos los datasource, en este caso son 2 spainDataSource y germanyDataSource

Otra propiedad importante pero no obligatoria que es defaultTargetDataSource, que en caso de no obtener una key válida en el método determineCurrentLookupKey entonces usar por defecto ese dataSource

Por último vamos a ver nuestro servicio rest

web.xml

Como vemos obtenemos el código del país por medio de una RequestParam y se lo pasamos a nuestro CountryDbContextHolder la key del país para seleccionar correctamente el datasource de ese país.

5. Ejemplo práctico

Para relizar el ejemplo práctico vamos a utilizar docker para desplegar nuestra aplicación en un contendor con tomcat y java 8.

Lo primero es crear nuestro war con el siguiente comando

Una vez creado nuestro war, procedemos a ejecutar nuestro war en contenedor de docker

Para comprobar si ha desplegado correctamente vamos a ver el log del contenedor, con el siguiente comando.

imagen1

Lo primero es ejecutar con el comando curl para obtener los equipos de España

Donde “dev” es el nombre de la máquina virtual donde se esta ejecutando docker.

Ahora vamos a obtener los equipos de Alemania

Por último vamos hacer una petición sin pasar el country

Como vemos obtenemos los esquipos de España como es lógico al no pasarle ningun código, el CountryRoutingDatasource va usar el datasource por defecto, en caso de no tener definido provocaria un IllegalStateException.

Con esto termina nuestra prueba con la clase AbstractRoutingDataSource.

6. Conclusiones

Como hemos visto spring no proporciona una clase para poder cambiar de dataSource en tiempo de ejecución de forma fácil y rápida. Solo implementado la clase AbstractRoutingDataSource

Espero que el tutorial os haya animado a usar (o al menos probar) esta utilidad que nos ofrece spring.

Puedes descargar el ejemplo de este tutorial desde aquí

7. Referencias

1 Comentario

Dejar respuesta

Please enter your comment!
Please enter your name here