2010-11-17 17 views
9

Tengo una aplicación que se conecta a MySQL usando JDBC. Hay casos en que la conexión JDBC permanece inactiva durante horas (tal vez incluso días) y pierde su conexión a MySQL y luego se exceptúa cuando intenta ejecutar una consulta. ¿Cuál es la mejor solución para esto?Una conexión persistente con JDBC a MySQL

Respuesta

15

Mantener la conexión abierta por un tiempo indeterminado es una mala práctica. El DB forzará un cierre cuando ha estado abierto por un tiempo demasiado largo. Debe escribir su código JDBC para que siempre cierre la conexión (y la declaración y el conjunto de resultados) en el bloque finally del mismo bloque try donde los ha adquirido para evitar la fuga de recursos como esta.

Sin embargo, adquirir la conexión en cada problema es, de hecho, una tarea bastante costosa, por lo que le gustaría usar un grupo de conexión . Los grupos de conexión decentes administrarán la apertura, la prueba, la reutilización y el cierre de las conexiones. Sin embargo, esto no implica que pueda cambiar su código JDBC para que nunca los cierre. Aún debe cerrarlos, ya que eso realmente liberaría la conexión subyacente al grupo para su reutilización futura.

Hay varias piscinas de conexión, como Apache DBCP que se singlethreaded pobres y por lo tanto en el rendimiento, C3P0 que es multiproceso y funciona mejor, y Tomcat JDBC para el caso de que usted está utilizando Tomcat y no desea utilizar el DBCP incorporado debido al mal desempeño.

Puede crear agrupaciones de conexiones mediante programación, aquí está un ejemplo con C3P0:

ComboPooledDataSource dataSource = new ComboPooledDataSource(); 
dataSource.setDriverClass("com.mysql.jdbc.Driver"); 
dataSource.setJdbcUrl("jdbc:mysql://localhost:3306/dbname"); 
dataSource.setUser("username"); 
dataSource.setPassword("password"); 

hacerlo una vez durante el inicio de la aplicación, a continuación, se puede usar de la siguiente manera:

Connection connection = null; 
// ... 

try { 
    connection = dataSource.getConnection(); 
    // ... 
} finally { 
    // ... 
    if (connection != null) try { connection.close(); } catch (SQLException ignore) {} 
} 

Cuando estás corriendo dentro de un contenedor compatible con JNDI como un servletcontainer (por ejemplo, Tomcat), luego también puede declararlo como java.sql.DataSource (manual específico de Tomcat here). A continuación, utilizará las instalaciones de agrupación de conexiones proporcionadas por servletcontainer. A continuación, puede adquirir el origen de datos de la siguiente manera:

DataSource dataSource = (DataSource) new InitialContext().lookup("java:comp/env/jdbc/YourDataSourceName"); 
+0

¿Por qué no mantener la conexión como miembro de la clase, verificar si está cerrado cuando planea usar e iniciar una nueva conexión si está cerrado? ¿Qué estaría mal con esto, excepto por tener un poco de memoria por un tiempo? –

+2

@EB: es inseguro. Relacionado: http://stackoverflow.com/q/9428573 Debe usar una conexión completamente separada por hilo y transacción.Se pueden mantener abiertos y volver a usar después de que hayan realizado su trabajo local transaccional, pero eso es exactamente lo que hace un grupo de conexiones. Un grupo de conexiones no cierra físicamente la conexión, solo la mantiene abierta y la prueba antes de liberarla (como ya se respondió en esta publicación) – BalusC

4

Hay bibliotecas, como Apache's DBCP que pueden agrupar conexiones. Una parte de esto es que pueden configurarse para probar automáticamente la conexión cuando vayas a usarla (como "SELECCIONAR AHORA() DESDE DOBLE", u otra cosa inofensiva) y restablecer automáticamente la conexión de forma transparente si es necesario, permitiendo que aplicación para pretender que la conexión es eterna.

+0

Este es el camino a seguir. Incluso puede configurarlo para hacer una SELECCIÓN ficticia antes de devolver la conexión al cliente para que sepa que funcionará. –

Cuestiones relacionadas