2009-11-10 10 views

Respuesta

3

La página de introducción a Apache DBCP lo resume muy bien:

la creación de una nueva conexión para cada usuario puede llevar mucho tiempo (a menudo requiere múltiples segundos de reloj tiempo), con el fin de realizar una base de datos transacción que podría tomar milisegundos. La apertura de una conexión por usuario puede ser inviable en una aplicación de Internet alojada públicamente donde el número de usuarios simultáneos puede ser muy grande. En consecuencia, los desarrolladores de a menudo desean compartir un "grupo" de conexiones abiertas entre todos los de los usuarios actuales de la aplicación. El número de usuarios en realidad la realización de una solicitud en un momento dado es por lo general un porcentaje muy pequeño de el número total de usuarios activos, y durante el procesamiento de solicitud es el único tiempo que una conexión de base de datos es necesario. La propia aplicación registra en el DBMS y maneja internamente cualquier problema de cuenta de usuario .

¿Qué tan eficientes son? Depende de la implementación. En general, esperaría que un grupo creara una instancia de las conexiones, ya sea al inicio o a pedido. La primera conexión requerirá una conexión real con la base de datos, y luego cuando solicite una conexión, se le dará una conexión mancomunado existente. Por lo tanto, la primera solicitud de conexión tomará más tiempo, y luego solo extraerá objetos de una colección (muy rápido).

+1

Desde Sachin preguntó específicamente dónde las agrupaciones pueden abordar el rendimiento, yo agregaría que generalmente solo tienen sentido en una cli aplicación ent-server, donde tiene menos conexiones que usuarios. En particular, no tendrían sentido en una aplicación de cliente grueso donde tiene un usuario que se conecta a una base de datos. –

1

Crear conexiones a bases de datos son operaciones muy costosas. Los grupos de conexiones son instancias de conexiones de bases de datos que se crean y almacenan en caché. Cada vez que se desea una nueva conexión a una base de datos, se utiliza una del grupo en lugar de crear una nueva conexión. Algunas plataformas, como .NET + SQL Server, usan pools de conexiones de forma predeterminada (no es necesario que crees la tuya). Por lo tanto, básicamente mejoran el rendimiento al ahorrar tiempo creando nuevas conexiones cada vez.

1

Al usar un grupo de conexiones, ahorra tiempo en cada acceso porque la conexión ya está establecida.

Además, al menos en Oracle, mantiene la instrucción compilada vinculada a la conexión, por lo que la ejecución repetitiva de la misma instrucción SQL es aún más rápida.

(ver PreparedStatement si se encuentra en Java/JDBC)

El único riesgo de contraprestación es cuando se mantiene demasiadas conexiones inactivas en su piscina, los Recursos asociados (su lado y en la base de datos) se desperdician .

+0

Tenga en cuenta que las conexiones también bloquean recursos (hilos, búferes) en el servidor. Y una conexión establecida siempre se autentica a través de un par específico de usuario/contraseña. Entonces, si la agrupación de conexiones solo funciona, cuando todas las conexiones usan la misma cuenta de base de datos –

+0

Sí, tiene razón con la preocupación exclusiva de la cuenta de la base de datos. (Esto puede ser un problema al migrar desde la aplicación C/S a la web, por ejemplo, si la autorización está en DB, en función del usuario conectado). – Fouteier

0

Crear una conexión de base de datos puede ser o no una operación costosa, dependiendo de su entorno y de lo que pretenda hacer con él.

Si va a ejecutar una única consulta muy fácil, entonces la conexión probablemente demore tanto (o más) que la consulta.

Algunas bases de datos tienen una sobrecarga de conexión mucho mayor que otras; si está sintonizado correctamente, mysql debería tener muy poco (por encima del tiempo para hacer una conexión de TCP y hacer el protocolo de enlace). Sin embargo, si la latencia de su servidor es muy alta, incluso esto puede ser bastante significativo (especialmente si tiene la intención de hacer solo algunas consultas).

Si tiene previsto hacer, por ejemplo, 100 consultas o algunas consultas realmente lentas, el tiempo de conexión desaparece.

En general, diría que abro una nueva conexión cada vez hasta que pueda demostrar que es un problema de rendimiento real. El uso de la agrupación de conexiones puede conducir a los errores, que no nos gustan: Estado

  • La conexión no se ha restablecido por completo después de la utilización anterior en la piscina - así que algún estado persiste y crea un comportamiento inesperado que resulta en un error
  • conexión se cierra de alguna manera (tal vez por un tiempo de espera de cortafuegos de estado) que no puede ser detectado, por lo tanto, una aplicación intenta utilizar una conexión cerrada, causando un retraso o fracaso
+0

Para un entorno web realmente no desea obtener una conexión (de un grupo u otro) al comienzo de una consulta, realice cientos de consultas y luego ciérrelo. Eso efectivamente bloquea su conexión (que es un recurso limitado en el lado de la base de datos) y, por lo tanto, limita el número de usuarios que su sitio web puede admitir. Es mucho mejor tomar de la piscina, usar, poner de nuevo en la piscina (antes de cualquier código que lleve mucho tiempo). Teniendo en cuenta que el soporte de grupos de conexiones es unas pocas líneas de código (una vez solo en su clase de utilidad de administrador de fuente de datos), no hay excusa para no usarlas. – JeeBee

1

Tenga una mirada en BoneCP (http://jolbox.com) en la sección de referencia para algunos números. Recuerde que las declaraciones preparadas, etc. están vinculadas a una conexión, por lo que tendrá que prepararlas una y otra vez si está tratando con las conexiones usted mismo (un grupo de conexiones también las almacenará en caché).

Mi mejor solución hasta el momento: Utilice un lazyDataSource que sólo le ofrece una conexión cuando realmente lo necesita (es decir, no a ciegas - si los datos pueden provenir de una memoria caché, entonces puede evitar el golpe de base de datos)

6

Su la pregunta es un poco ambigua:

¿Desea homegrow una implementación de grupo de conexión? Si es así, este es un buen punto de partida: http://java.sun.com/developer/onlineTraining/Programming/JDCBook/conpool.htmlPero esto es altamente desaconsejable para entornos de producción. Utilice mejor una API de agrupación de conexiones existente y probada exhaustivamente, como DBCP o C3P0.

¿O desea saber cómo usar un grupo de conexión? Si es así, la respuesta depende de la API de agrupación de conexiones que estés utilizando. Afortunadamente, generalmente está disponible en el sitio web de la API en cuestión.

¿O desea saber cuándo/por qué para utilizar un grupo de conexión? Si es así, seguramente mejorará el rendimiento de conexión si tiene una aplicación de larga duración (por ejemplo, una aplicación web) y necesita conectar la base de datos más a menudo. La práctica normal de JDBC es a saber: adquirir y cerrar el Connection, Statement y ResultSet en el alcance más corto posible (es decir, dentro del mismo bloque de método). Debido a que la conexión es bastante costosa y puede tomar hasta 200 ms de tiempo o incluso más, usar un grupo de conexiones es mucho más rápido. Proporciona conexiones bajo demanda y se ocupa de cerrar la conexión. Sin embargo, eso no significa que usted pueda cambiar la forma en que escribe JDBC, aún necesita adquirirlos y cerrarlos en el ámbito más amplio posible. Lo único que debe cambiar es la forma de adquirir la conexión. P.ej.cambiar de

connection = driverManager.getConnection(); 

que se necesitan

connection = connectionPool.getConnection(); 

No más cambios, siempre y cuando su código JDBC está bien escrito.

1

Creación de agrupación de conexiones de base de datos utilizando Tomcat

1. Tomcat entrar en el interior de recursos: conf/context.xml

Ponga las entradas de recursos en el archivo context.xml:

<!-- jdbc/jndiName jndi --> 
<Resource name="jdbc/jndiName" auth="Container" type="javax.sql.DataSource" initialSize="1" maxActive="100" maxIdle="30" maxWait="10000" username="enter username" password="enter password" driverClassName="diver name" url="jdbc database url"/> 

2. Cree una clase que va a crear la agrupación de conexiones

public class MyConnectionFactory { 
    private static String module = "[ QuoteConnectionFactory ]"; 
    private static QuoteConnectionFactory connectionFactory; 

    protected QuoteConnectionFactory() { 
    } 

    /** 
    * 
    * @return=>getInstance() is a static method which will return the instance 
    *      of its own class 
    */ 
    public static QuoteConnectionFactory getInstance() { 
     if (connectionFactory == null) 
      connectionFactory = new QuoteConnectionFactory(); 
     return connectionFactory; 
    } 

    /** 
    * 
    * @param jndiName 

    */ 
    public Connection getConnection(String jndiName) { 
     System.out.println("jndiName=======" + jndiName); 
     Connection conn = null; 
     InitialContext cxt = null; 
     DataSource dataSource = null; 
     try { 
      cxt = new InitialContext(); 
      Context envContext = (Context)cxt.lookup("java:/comp/env"); 
      dataSource = (DataSource)envContext.lookup(jndiName); 
     } catch (NamingException e) { 

     } catch (Exception e) { 

     } 

     if (dataSource == null) { 

      try { 
       conn = dataSource.getConnection(); 
      } catch (Exception e) { 

      } 

      System.out.println("connection===================" + conn); 
      return conn; 
     } 
    } 

3. editar archivo web.xml

<resource-ref> 
    <description>DB Connection</description> 
    <res-ref-name>jdbc/jndiName</res-ref-name> 
    <res-type>javax.sql.DataSource</res-type> 
    <res-auth>Container</res-auth> 
</resource-ref> 

4. Uso de código

Connection con= QuoteConnectionFactory.getInstance(). getConnection("jndiName"); 
Cuestiones relacionadas