Tengo una aplicación Java que usa una base de datos de Postgres y estoy tratando de introducir PGPool para ampliar mi base de datos. Me encuentro con un problema donde Postgres arroja el siguiente error: unnamed prepared statement does not exist
. Después de subir el registro en Postgres veo el siguiente material pasando por cada instrucción de selección mi aplicación se ejecuta:Consultas de Java contra PGPool II porque los errores de la "declaración preparada sin nombre no existe"
EDTLOG: 00000: duration: 7.585 ms parse <unnamed>: "my select statement here"
EDTLOG: 00000: duration: 0.088 ms bind <unnamed>: "my select statement here"
EDTLOG: 00000: duration: 79.014 ms execute <unnamed>: "my select statement here"
Pero a veces, entre los análisis gramatical se unen ejecutar pasos// PGPool ejecutará algunas consultas adicionales, por lo que el registro se parece a esto:
EDTLOG: 00000: duration: 7.585 ms parse <unnamed>: "my select statement here"
EDTLOG: 00000: duration: 0.088 ms bind <unnamed>: "my select statement here"
EDTLOG: 00000: duration: 0.328 ms statement: SELECT count(*) FROM pg_class AS c, pg_namespace AS n WHERE c.relname = 'my_table' AND c.relnamespace = n.oid AND n.nspname = 'pg_catalog'
EDTLOG: 00000: duration: 79.014 ms execute <unnamed>: "my select statement here"
EDTERROR: 26000: unnamed prepared statement does not exist
EDTLOG: 00000: duration: 0.022 ms parse S_2: ROLLBACK
EDTLOG: 00000: duration: 0.005 ms bind S_2: ROLLBACK
EDTLOG: 00000: duration: 0.008 ms execute S_2: ROLLBACK
por lo que entiendo, porque la consulta no tiene nombre que se tira por las Postgres si otro viene en consulta durante la sesión de base de datos antes de ejecutar la consulta sin nombre. Entonces, como PGPool a veces emite estas consultas adicionales entre los pasos de análisis/vinculación/ejecución, está causando que la consulta se descarte.
Lo primero que pensé fue que quizás mi aplicación Java no necesitaba enviar sentencias parse/bind/execute para cada consulta. Pero parece que este es el comportamiento predeterminado del controlador JDBC de Postgres desde la versión 3 de JDBC y Postgres 7.4 http://jdbc.postgresql.org/documentation/head/server-prepare.html. Supongo que podría intentar deshabilitar por completo las declaraciones preparadas del lado del servidor, pero la documentación no especifica cómo hacerlo, y no estoy seguro de que sea algo que quiera hacer de todos modos.
Mi segunda idea fue hacer que PGPool II dejara de enviar esas consultas de metadatos. Como solo estoy tratando de usar PGPool como equilibrador de carga, realmente no veo por qué necesita saber todo sobre los metadatos de mi tabla. Seguí el código que está ejecutando esas consultas en el método is_system_catalog de la fuente PGPool aquí: https://github.com/iakio/pgpool-II/blob/master/pool_select_walker.c#L256 Parece que PGPool quiere saber sobre las relaciones de mi tabla por alguna razón, y desafortunadamente no veo ninguna forma de desactivar ese comportamiento.
Cualquier idea sobre cómo solucionar este problema sería muy apreciada.
Algunos información sobre mi entorno:
JDBC Driver: postgresql-9.1-901.jdbc4.jar
Java version "1.6.0_31"
Spring 3.1 managed JPA
Hibernate 3.5
Postgres 9.1
ACTUALIZACIÓN: He encontrado una solución para el problema. Al colocar protocolVersion=2
en la URL de JDBC, básicamente le dice al controlador JDBC de Postgres que no use las declaraciones preparadas del lado del servidor. Esto permite que mi aplicación se ejecute mientras uso PGPool II en frente de mi base de datos. Me molesta el hecho de que tengo que recurrir al protocolo de la versión 2 de JDBC solo para usar PGPool.
@Zecas Sí, sé cómo funciona el sitio, no es necesario que me lo expliques. Todavía no tengo una solución que me permita usar la última versión de JDBC contra PGPool II. En lo que a mí respecta, esta sigue siendo una pregunta abierta. –
Es posible que desee asegurarse de que sus consultas se ejecutan dentro de una transacción. La declaración preparada se descartará si se produce otra transacción en la misma conexión. Por defecto, el controlador jdbc postgresql no usa transacciones, lo cual me parece un poco extraño. Puede establecer el comportamiento transaccional en persistence.xml si lo recuerdo. – PlexQ
¿Por qué está usando PgPool? ¿No puedes usar DBCP, BoneCP o c3p0 para administrar directamente el grupo de conexiones desde tu aplicación? – Chochos