Pregunta

Tengo un programa Java que consta de unos 15 métodos. Y, estos métodos se invocan con mucha frecuencia durante la ejecución del programa. Por el momento, estoy creando una nueva conexión en cada método e invocando declaraciones sobre ellos (la base de datos está configurada en otra máquina en la red).

Lo que me gustaría saber es: ¿Debería crear solo una conexión en el método principal y pasarla como argumento a todos los métodos que requieren un objeto de conexión, ya que reduciría significativamente el número de objetos de conexión en el programa, en lugar de crear y cerrar conexiones con mucha frecuencia en todos los métodos.

Sospecho que no estoy usando los recursos de manera muy eficiente con el diseño actual, y hay muchas posibilidades de mejora, considerando que este programa podría crecer mucho en el futuro.

¿Fue útil?

Solución

Sí, debería considerar reutilizar las conexiones en lugar de crear una nueva cada vez. El procedimiento habitual es:

  • adivine cuántas conexiones simultáneas puede manejar su base de datos de manera sensata (por ejemplo, comience con 2 o 3 por CPU en la máquina de la base de datos hasta que descubra que esto es muy poco o demasiado; tenderá a depender sobre cuán vinculadas al disco están sus consultas)
  • cree un grupo de tantas conexiones: esencialmente una clase a la que puede solicitar " la próxima conexión gratuita " al comienzo de cada método y luego "devolver" al grupo al final de cada método
  • su método getFreeConnection () necesita devolver una conexión gratuita si hay una disponible, de lo contrario (1) cree una nueva, hasta el número máximo de conexiones que haya decidido permitir, o (2) si el máximo ya están creados, espere a que uno sea gratuito
  • Recomendaría la clase Semaphore para administrar las conexiones; De hecho, tengo un breve artículo en mi sitio web sobre administrando un grupo de recursos con un semáforo con un ejemplo que creo que podrías adaptar a tu propósito

Un par de consideraciones prácticas:

  • Para un rendimiento óptimo, debe tener cuidado de no `` acaparar '' una conexión mientras no la estás utilizando para ejecutar una consulta . Si toma una conexión del grupo una vez y luego la pasa a varios métodos, debe asegurarse de no hacerlo accidentalmente.
  • ¡No olvides devolver tus conexiones a la piscina! (prueba / finalmente es tu amigo aquí ...)
  • En muchos sistemas, no puede mantener las conexiones abiertas 'para siempre' : el O / S las cerrará después de un tiempo máximo. Por lo tanto, en su método de 'devolver una conexión al grupo', tendrá que pensar en las conexiones 'retiradas' que han existido durante mucho tiempo (cree algún mecanismo para recordar, por ejemplo, al tener un objeto contenedor alrededor de un objeto de conexión JDBC real que puede usar para almacenar métricas como esta)
  • Es posible que desee considerar el uso de declaraciones preparadas.
  • Con el tiempo, probablemente necesite ajustar el tamaño del grupo de conexiones

Otros consejos

Puede pasar la conexión o, mejor aún, usar algo como Agrupación de conexiones de base de datos de Yakarta. http://commons.apache.org/dbcp/

Debería usar un grupo de conexiones para eso.

De esa forma, puede solicitar la conexión y liberarla cuando haya terminado y devolverla al grupo

Si otro hilo quiere una nueva conexión y esa está en uso, se podría crear una nueva. Si ningún otro hilo está usando una conexión, el mismo podría ser reutilizado.

De esta manera, puede dejar su aplicación de alguna manera (y sin pasar la conexión por todas partes) y seguir utilizando los recursos correctamente.

Desafortunadamente, los ConnectionPools de primera clase no son muy fáciles de usar en aplicaciones independientes (son los predeterminados en los servidores de aplicaciones) Probablemente un microcontenedor (como Sping) o un buen marco (como Hibernate) podría permitirle usar uno.

Sin embargo, no son demasiado difíciles de codificar desde cero.

:)

Esta búsqueda en Google ayudará para encontrar más sobre cómo usar uno.

Hojear

Muchos controladores JDBC hacen la agrupación de conexiones por usted, por lo que hay pocas ventajas en la agrupación adicional en este caso. Le sugiero que consulte la documentación de su controlador JDBC.

Otro enfoque para los grupos de conexión es

  • Tener una conexión para todo el acceso a la base de datos con acceso sincronizado. Esto no permite la concurrencia, pero es muy simple.
  • Almacene las conexiones en una variable ThreadLocal (override initialValue ()) Esto funciona bien si hay un pequeño número fijo de hilos.

De lo contrario, sugeriría usar un grupo de conexiones.

Si su aplicación es de un solo subproceso, o realiza todas sus operaciones de base de datos desde un solo subproceso, está bien usar una sola conexión. Asumiendo que no necesita múltiples conexiones por cualquier otra razón, esta sería, con mucho, la implementación más simple.

Dependiendo de su controlador, también puede ser posible compartir una conexión entre subprocesos; esto también estaría bien si confía en que su controlador no mienta sobre su seguridad de subprocesos. Consulte la documentación del controlador para obtener más información.

Normalmente, los objetos debajo de "Conexión" no se puede usar de manera segura desde varios subprocesos, por lo que generalmente no es aconsejable compartir ResultSet, objetos de declaración, etc. entre subprocesos; la mejor política es, con mucho, usarlos en el mismo subproceso que los creó; esto normalmente es fácil porque esos objetos generalmente no se guardan por mucho tiempo.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top