====== 06 - Pool de conexiones ====== Abrir una conexión es caro: negociación de red, autenticación y una sesión reservada en el servidor. Pagar ese precio por cada operación — como hasta ahora — funciona en clase, pero con muchas consultas simultáneas agota la base de datos. Un **pool de conexiones** abre las conexiones **de antemano** y las **reutiliza**. ===== 1. Cómo funciona ===== @startuml participant "DAO" as dao participant "Pool" as pool participant "MariaDB" as db == Al arrancar == pool -> db : crea las conexiones == En cada operación == dao -> pool : getConnection() pool --> dao : Connection dao -> db : sentencias dao -> pool : close() note over pool : no se cierra: vuelve al pool @enduml * ''getConnection()'' **presta** una conexión libre del pool. * ''close()'' **devuelve** la conexión al pool: no cierra nada de verdad. * Si el pool está vacío, el que pide espera hasta un máximo; agotarlo de forma constante indica pool corto o conexiones retenidas demasiado tiempo. ===== 2. DataSource ===== JDBC define la interfaz ''javax.sql.DataSource'': una **fábrica de conexiones** que sustituye a ''DriverManager''. Con la librería estándar de facto, **HikariCP**, la clase ''DbConnection'' no cambia de nombre ni de firma; cambia su contenido: com.zaxxer HikariCP 5.1.0 public final class DbConnection { private static final HikariDataSource DATA_SOURCE = buildDataSource(); private static HikariDataSource buildDataSource() { HikariConfig config = new HikariConfig(); config.setJdbcUrl(PROPERTIES.getProperty("db.url")); config.setUsername(PROPERTIES.getProperty("db.user")); config.setPassword(PROPERTIES.getProperty("db.password")); config.setMaximumPoolSize(10); return new HikariDataSource(config); // abre el pool al crearla } // misma firma que antes: el DAO ni se entera public static Connection get() throws SQLException { return DATA_SOURCE.getConnection(); } } ^ Ajuste ^ Función ^ | ''maximumPoolSize'' | Conexiones máximas del pool; 10 es un punto de partida razonable | | ''connectionTimeout'' | Milisegundos de espera al pedir conexión antes de fallar | El pool se **crea** al arrancar la aplicación y se **cierra** al terminar: DATA_SOURCE.close(); // apagado de la aplicación, no de cada operación ===== 3. Consecuencias para el código ===== ^ Regla ^ Motivo ^ | ''try-with-resources'' en todas las operaciones | ''close'' devuelve la conexión al pool; olvidarla es robarle conexiones al resto | | Transacciones cortas | Una transacción abierta retiene su conexión; muchas retenciones vacían el pool | | Misma API | ''Connection'', ''PreparedStatement'' y el resto no cambian: solo cambia de dónde viene la conexión | Todo el código de los temas anteriores funciona tal cual sobre el pool: el DAO sigue llamando a ''DbConnection.get()'' y cerrando con ''try-with-resources''. Lo único que ha cambiado es el significado de ''close()''.