2011-05-23 16 views
7

Tengo una pregunta sobre el uso general de la declaración preparada junto con la agrupación de conexiones.Declaraciones preparadas junto con Connection Pooling

Las declaraciones preparadas generalmente están vinculadas a una sola conexión. En nuestra aplicación, un estado preparado se crea al inicio y se ejecuta en un momento posterior.

Si en el momento de la ejecución de una determinada declaración preparada específica, la conexión asociada a la declaración preparada está ocupada ejecutando otras declaraciones de cómo se ejecutará esta declaración requerida. ¿Esta instrucción esperará a que la conexión se libere o esta afirmación tener preferencia en la ejecución?

actualización

que han probado esta siguiendo función SLEEP() con la base de datos Derby Apache, que llama a la función del sueño en java TimeHandlingTest clase.

CREAR FUNCIÓN DORMIR() DEVOLUCIONES INTEGER IDIOMA JAVA PARÁMETRO ESTILO JAVA SIN NOMBRE EXTERNO SQL 'com.derby.test.TimeHandlingTest.sleep';

Y realizó dos declaraciones preparadas desde una conexión y llamó a la función Sleep() desde una instrucción preparada y una simple sql select con otra. La selección simple sql tomó casi el mismo tiempo (10s) para la cual la primera declaración preparada estaba durmiendo. Esto significa que un objeto de conexión no puede ser usado para ejecución por más de una declaración preparada a la vez. Por favor corrígeme si estoy equivocado.

+0

¿Su código se está ejecutando en un servidor de aplicaciones? La respuesta varía cuando utiliza un DataSource en lugar de un DriverManager para obtener la conexión. –

+0

@Vineet: Nuestra aplicación es una aplicación Java simple que no se ejecuta en el servidor de aplicaciones. Estamos recibiendo conexiones del administrador del controlador. –

Respuesta

8

No puede devolver el Connection al grupo si planea utilizar el PreparedStatement.

En otras palabras: solo puede usar un PreparedStatement construido a partir de un Connection que tiene actualmente.

+0

Esto no parece ser una solución razonable ya que mi aplicación requeriría conexiones como declaraciones preparadas. –

+1

¡Esto no es una solución, es un requisito! Si no sigues esto, entonces estarás teniendo problemas tarde o temprano. –

1

Esto suena como una forma inusual de utilizar su grupo de conexiones. A pesar de que las conexiones están en un grupo, solo deberían ser usadas por un hilo a la vez. Tiendo a crear la declaración preparada y la uso muy cerca del punto de creación. Además, algunos controladores JDBC ahora son compatibles con el almacenamiento en caché de Statement que reduce la sobrecarga de usarlo de esta manera.

4

El valor de PreparedStatement reside en la capacidad de la base de datos para crear un plan de ejecución para la declaración que se puede reutilizar para parámetros arbitrarios y por lo tanto es de naturaleza genérica (por supuesto que requiere que use parámetros en su declaración) , por ejemplo

PreparedStatement pstmt = con.prepareStatement("UPDATE EMPLOYEES 
           SET SALARY = ? WHERE ID = ?"); 
pstmt.setBigDecimal(1, 153833.00); 
pstmt.setInt(2, 110592); 

Si por el contrario se utilizaría la concatenación de cadenas para pegar los valores de los parámetros en el código SQL, la base de datos no sería capaz de construir un plan de ejecución genérico. por lo tanto no habría ninguna diferencia si se utilice una declaración o declaración preparada, por ejemplo,

PreparedStatement pstmt = con.prepareStatement("UPDATE EMPLOYEES 
           SET SALARY = 1200 WHERE ID = 3"); 

no podría utilizar la ventaja de PreparedStatements.

Su pregunta implica que desea reutilizar el objeto PreparedStatement, que no es necesario. Por supuesto, si puede usar un objeto PreparedStatement para actualizar varios valores, etc., es un uso más eficiente de los recursos. Sin embargo, la vida útil (o al menos la duración útil) de PreparedStatement está vinculada a Connection, por lo tanto, si llama a conn.close(), el PreparedStatement queda inutilizado. Sin embargo, la mayoría de los buenos controladores en una situación de agrupación reutilizan los mismos objetos PreparedStatement nuevamente. En resumen, no guarde en caché el PreparedStatement independientemente de la conexión.

+0

Gracias por la respuesta, pero mi pregunta principal es que si la conexión asociada a mi declaración preparada está ocupada ejecutando cualquier otra declaración preparada, ¿cómo se ejecutará mi declaración de preparación? ¿Podemos ejecutar múltiples declaraciones preparadas con una única conexión en un momento determinado? \ –

0

Una forma de evitar esto es mantener un caché donde las conexiones se asignan a las declaraciones preparadas. Cuando obtiene una conexión del pool, compruebe si está correlacionado con la declaración preparada que se va a ejecutar. De lo contrario, pase la declaración preparada al controlador JDBC para que se compile. Luego mapea a la conexión. La desventaja de este enfoque es que más de una conexión puede obtener copias de la misma declaración preparada. Pero parece que this is what some J2EE servers do.

2

Suponiendo que se trata de una aplicación de subprocesos múltiples, los objetos Connection se suelen asociar a un único subproceso en cualquier momento. Connection los objetos adquiridos por un subproceso no se devuelven al grupo hasta que se cierran. Esto se aplica tanto al contenedor de conexión lógica (que normalmente es devuelto por un DataSource administrado por un servidor de aplicaciones) a la aplicación, como a la conexión física. Además, las conexiones físicas se pueden compartir a través de múltiples conexiones lógicas siempre que sean parte de la misma transacción.

Esto significa que si se devuelve un identificador de conexión lógica a su aplicación, no es necesario que la conexión física subyacente sea la misma y se contenga (a menos que sea parte de la misma transacción). Si se espera que su aplicación maneje usuarios concurrentes sin ningún tipo de molestia, se crearía un objeto Connection en cada subproceso que inicie una transacción, y este objeto no se disputará en los subprocesos. Debajo del capó, diferentes conexiones físicas en el grupo estarían ejecutando las consultas SQL asociadas con las declaraciones preparadas, a través de múltiples hilos, nuevamente sin ninguna contención.

+0

Gracias por la respuesta. Según mi entender, las declaraciones preparadas se almacenan en caché según la conexión física y no según la conexión lógica. Si esa conexión física ya está ocupada en la ejecución de la declaración, entonces podemos ejecutar otra declaración preparada en la misma conexión física o hacer necesitamos recrear esta declaración preparada con una conexión gratuita disponible desde el grupo. –

Cuestiones relacionadas