Si símplemente vas a hacer una pequeña aplicación java con acceso a base de datos para probar o que no va a llevar muchos usuarios simultáneos o muchos hilos simultáneos intentando acceder a base de datos, puedes saltarte este apartado y pasar el siguiente.
Aquí vamos a ver como optimizar el tema de conexiones a base de datos cuando nuestra aplicación es compleja, tiene muchos hilos que intentan acceder simultáneamente a base de datos o muchos usuarios. Es el típico caso de aplicaciones web en el que puede haber varios usuarios accediendo simultáneamente.
El problema con las conexiones
Cuando nuestro programa java va a realizar alguna operación con base de datos, tenemos básicamente dos formas de proceder en lo que respecta al tema de conexiones con la base de datos.
- Abrir la conexión, realizar las operaciones que queramos y cerrar la conexión. Para las siguientes operaciones que queramos realizar, volvemos a hacer lo mismo: abrir conexión, realizar operaciones y cerrar. Este mecanismo no es adecuado si vamos a abrir y cerrar la conexión muchas veces, puesto que abrir y cerrar es algo costoso, consume recursos y tiempo de CPU. Si hay varios usuarios a la vez realizando operaciones y cada vez se abre y se cierra una conexión, el rendimiento total puede ser pobre.
- Abrir una conexión y dejarla abierta, de forma que todo el que necesite realizar una operación de base de datos usa esa única conexión. El problema de esta opción es que una conexión de base de datos no se puede usar simultáneamente por varios hilos, por lo que es necesario sincronizar el acceso a ella. De esta forma, mientras un hilo/cliente está realizando una operación con la base de datos, los demás hilos/clientes deben estar a la espera de que se libere la conexión. Si hay muchos clientes trabajando simultáneamente, se van a pasar mucho tiempo esperando unos por otros
El pool de conexiones
La forma de solucionar estos problemas es tener un Pool de conexiones. Un Pool de conexiones no es más que una clase java que abre en el arranque varias conexiones a base de datos. Cuando alguien necesita una conexión, se la pide a esta clase (al Pool de conexiones). El Pool devuelve una de las conexiones que tiene abiertas y la marca como que está siendo usada. Si alguien le pide más adelante otra conexión, buscará una que no esté siendo usada y se la devolverá. Cuando se termine de hacer las operaciones con base de datos, simplemente le indicamos al Pool de conexiones que hemos terminado con la conexión. Este la marcará como libre y se la dará a otro que la pida.
De esta forma tenemos varias conexiones permanentemente abiertas y el Pool se encarga de que no haya varios hilos/clientes usando simultáneamente la misma conexión.
Apache BasicDataSource
Java no tiene por defecto ningún Pool de conexiones, pero si tiene la interface DataSource, que es la interface que deben implementar los Pool de conexiones. Básicamente tiene un método getConnection() para pedirle una conexión disponible con base de datos. Este nos devolverá algo que implementa la interface Connection y que podremos usar como una conexión a base de datos. La diferencia con una conexión normal a base de datos está en el método close(). En una conexión normal, este método cierra la conexión. En una conexión obtenida a través de un DataSource/Pool de conexiones, este método le indica al Pool que ya no necesitamos más la conexión, por lo que realmente no se cierra, sino que sólo se marca como libre para otro hilo que la solicite.
Una implementación bastante usada de DataSource es Apache BasicDataSource. Para poder usarla debemos bajarnos la última versión de commons-dbcp y añadirla a nuestro proyecto java, bien en el classpath, bien en nuestro IDE favorito.
Una vez descargado y puesto en nuestro proyecto, podemos instanciar y configurar el Pool de esta manera
BasicDataSource basicDataSource = new BasicDataSource();
basicDataSource.setDriverClassName("com.mysql.jdbc.Driver");
basicDataSource.setUsername("usuario");
basicDataSource.setPassword("password");
basicDataSource.setUrl("jdbc:mysql://servidor/base_datos");
basicDataSource.setValidationQuery("select 1");
Simplemente hemos hecho un new y a base de métodos set() le vamos pasando los parámetros para que el Pool sepa establecer las conexiones. Son los mismos parámetros que hemos pasado en el apartado anterior. El único que difiere un poco es el setValidationQuery(), que es alguna SQL propia de la base de datos y que devuelva al menos un resultado (tan tonta como la del ejemplo). De esta forma, el Pool puede comprobará esa validation query que la conexión es correcta.
Ahora, cuando queramos hacer alguna transacción con base de datos, simplemente hacemos un código como este
public void hazUnaTransaccion (DataSource dataSource) {
// Se le pide al Pool una conexion
Connection conexion = dataSource.getConnection();
// Aqui la consulta, insercion, modificacion o borrados
// que queramos hacer.
// Se indica al Pool que ya hemos terminado con la conexion
conexion.close();
}
- Login to post comments
