2011-01-10 15 views
6

Todos knowthat preferimos reutilizar un JDBC PreparedStatement que crear una nueva instancia dentro de un bucle.¿Reutilización de una declaración preparada entre métodos?

Pero, ¿cómo lidiar con PreparedStatement reutilizar entre invocaciones a diferentes métodos? ¿La reutilización "regla" todavía cuenta?

¿Debo realmente considerar el uso de un campo para el PreparedStatement o debería cerrar y volver a crear la declaración preparada en cada invocación (mantenerlo local)? (Por supuesto, una instancia de dicha clase estaría vinculada a un Connection que podría ser una desventaja en algunas arquitecturas)

Soy consciente de que la respuesta ideal podría ser "depende".
Pero estoy buscando una mejor práctica para los desarrolladores con menos experiencia que harán la elección correcta en la mayoría de los casos.

+3

Definitivamente no lo convierten en un campo de la clase. Mantenerlo methodlocal. – BalusC

Respuesta

13

Por supuesto una instancia de una clase tal estaría obligado a una conexión que puede ser una desventaja

puede estar? sería una desventaja de enorme desventaja. Tendría que sincronizar el acceso a él, lo que mataría su rendimiento de usuario múltiple con la piedra muerta, o crear varias instancias y mantenerlas en un grupo. Gran dolor en el culo

La agrupación de instrucciones es el trabajo del controlador JDBC, y la mayoría, si no todos, de la cosecha actual de controladores hacen esto por usted. Cuando llame al prepareStatement o al prepareCall, el controlador manejará la reutilización del recurso existente y las declaraciones precompiladas.

Statement Los objetos están vinculados a una conexión, y las conexiones se deben utilizar y devolver a la agrupación lo más rápido posible.

En resumen, la práctica habitual de la obtención de un PreparedStatement en el inicio del método, usando repetidamente dentro de un bucle, a continuación, cerrándola al final del método, es mejores prácticas.

+0

No entiendo por qué esto es un gran problema. Tienes un hilo por conexión. Cada clase de servicio (que contiene sus métodos CRUD) construye PreparedStatements por adelantado y los reutiliza en todos los métodos. Los estados preparados se cierran cuando se cierra la conexión. – Gili

0

Sí, puede reutilizarse, pero creo que esto solo cuenta si se usa el mismo objeto Connection y si está utilizando un grupo de conexión de base de datos (desde una aplicación web, por ejemplo) entonces los objetos Connection serán potencialmente diferente cada vez.

Siempre recreo el PreparedStatement antes de cada uso dentro de una aplicación web por este motivo.

¡Si no está utilizando un grupo de conexión, entonces está dorado!

0

No veo la diferencia: si ejecuto la misma instrucción repetidamente contra la misma conexión, ¿por qué no reutilizar el PreparedStatement de alguna manera? Si varios métodos ejecutan la misma instrucción, entonces tal vez esa declaración debe ser encapsulada en su propio método (o incluso en su propia clase). De esa forma no necesitaría pasar un PreparedStatement.

+1

Dado que un Estado Preparado "pertenece" a una Conexión específica, simplemente no puede reutilizarlo entre diferentes Conexiones. Por supuesto, puede reutilizar algún código que se ejecutará a lo largo de diferentes Conexiones, pero lo bueno de un PreparedStatment es dejarlo preparado una vez y reutilizarlo, lo cual no es posible una vez que utiliza una Conexión diferente. –

6

Muchas cargas de trabajo de bases de datos están vinculadas a CPU, no a IO. Esto significa que la base de datos termina gastando más tiempo en el trabajo, como analizar consultas SQL y descubrir cómo manejarlas (haciendo el 'plan de ejecución'), de lo que gasta accediendo al disco.Esto es más cierto para las cargas de trabajo "transaccionales" que para las cargas de trabajo de "informes", pero en ambos casos, el tiempo empleado en preparar el plan puede ser más de lo que esperaba.

Por lo tanto, siempre es una buena idea, si la declaración se va a ejecutar con frecuencia y la molestia de hacer arreglos (correctos) para almacenar en caché PreparedStatements 'entre invocaciones a métodos' justifica su tiempo de desarrollador. Como siempre sucede con el rendimiento, la medición es clave, pero si puede hacerlo de manera económica, guarde en caché su Estado Preparado por hábito.

Algunos controladores JDBC y/o grupos de conexiones ofrecen un "caché de declaraciones preparado" transparente, para que no tenga que hacerlo usted mismo. Siempre que comprenda el comportamiento de su estrategia de caché transparente elegida en particular, está bien dejar que se haga un seguimiento de las cosas ... lo que realmente quiere evitar es el acierto en la base de datos.

+0

Hay muchas consultas acertadas que requerirán mucho IO en la base de datos. Específicamente, cualquier cosa que haga computación/agregación/... de grandes conjuntos de datos. –

+0

@Jochaim Sauer: Califiqué mis aserpías :-) –

Cuestiones relacionadas