2009-07-24 18 views
10

Desafortunadamente setTimeout no está implementado para JDBC/postgres. ¿Hay alguna manera de simular o solucionar esto? Funcionalmente quiero ejecutar la consulta y luego interrumpirla si lleva más tiempo que N segundosConsulta de postgres de JDBC con un tiempo de espera

+0

Encontré esta pregunta y respuesta útiles también para un problema de python/psycopg2 que encontré. Psycopg2 parece haber permitido la configuración del tiempo de espera en el momento de la conexión, pero esta interfaz se eliminó en mi caso. Agregando este comentario para beneficiar a otros que buscan en SO. – SetJmp

Respuesta

17

El "statement_timeout" se parece a lo que desea.

SET statement_timeout TO 1000; -- for a second 
<your_query_here>; 
RESET statement_timeout; -- reset 
+3

Es mejor que use RESET statement_timeout; una vez completada la consulta, en caso de que haya un valor predeterminado ... –

+0

Solucionado ahora, ¡gracias! –

+0

Probado esto en pgAdmin3. Solo funcionó cuando el SET statement_timeout se ejecuta por separado de la consulta real. Cuando se ejecutan juntos, pgAdmin3 usa lo que sea que el valor de tiempo de espera ya haya sido establecido y no use el proporcionado con la consulta. – Babar

1

Una forma podría ser intentar ejecutar la consulta en una clase Timer. Lanza una excepción si el temporizador finaliza sin un valor devuelto.

Hibernate y JDO suministran tal construcción. Tal vez sean buenas alternativas para ti.

+0

Tienes que tener cuidado de cómo se implementa esto; si se hace incorrectamente, terminas con muchos hilos bloqueados que contienen conexiones SQL que simplemente están siendo ignoradas. Parte del problema aquí es que no se puede obligar a un hilo a lanzar una excepción si está en medio de hacer algo. –

0

¿Qué sucede si utiliza c3p0 para su dataSource? Tiene muchas opciones configurables, y para bases de datos y redes malhumoradas, por ejemplo, acquireRetryAttempts, acquireRetryDelay y breakAfterAcquireFailure.

0

El uso de la palabra clave LOCAL limita el alcance del statement_timeout a la transacción actual. De esta forma, si algo sale mal (por ejemplo, se agota el tiempo de espera), se restablece el tiempo de espera.

BEGIN TRANSACTION; 
SET LOCAL statement_timeout TO 1000; -- one-second timeout 
SELECT COUNT(*) FROM really_huge_table; -- your slow query 
ROLLBACK;        -- reset 
Cuestiones relacionadas