2009-07-24 10 views
10

Leider setTimeout ist nicht für JDBC/Postgres implementiert. Gibt es eine Möglichkeit, dies zu simulieren oder zu umgehen? Funktionell möchte ich die Abfrage ausführen und die Pause dann, wenn es länger als N Sekunden dauertJDBC postgres Abfrage mit einem Timeout

+0

Ich fand diese Frage und Antwort hilfreich auch für ein Python/psycopg2 Problem, das ich angetroffen habe. Psycopg2 scheint Timeout-Einstellungen zum Zeitpunkt der Verbindung zuzulassen, aber diese Schnittstelle wurde in meinem Fall abstrahiert. Fügen Sie diesen Kommentar hinzu, um anderen Nutzern bei der Suche nach SO zu helfen. – SetJmp

Antwort

17

Die "statement_timeout" sieht aus wie Sie wollen.

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

Sie sind besser dran mit RESET statement_timeout; nachdem die Abfrage abgeschlossen ist - falls es einen Standardwert gibt ... –

+0

Jetzt behoben, danke! –

+0

Getestet auf pgAdmin3. Funktioniert nur, wenn das SET-Statement_timeout getrennt von der eigentlichen Abfrage ausgeführt wird. Wenn pgAdmin3 zusammen ausgeführt wird, verwendet es, was auch immer der Timeout-Wert war, und verwendet nicht den, der mit der Abfrage bereitgestellt wurde. – Babar

1

Eine Möglichkeit könnte sein, zu versuchen, die Abfrage in einer Timer-Klasse auszuführen. Wirf eine Ausnahme, wenn der Timer endet, ohne dass ein Wert zurückgegeben wird.

Hibernate und JDO liefern ein solches Konstrukt. Vielleicht wären sie eine gute Alternative für dich.

+0

Sie müssen vorsichtig sein, wie dies implementiert wird; Wenn es falsch gemacht wird, enden Sie mit vielen blockierten Threads, die SQL-Verbindungen enthalten, die gerade ignoriert werden. Ein Teil des Problems hier ist, dass Sie einen Thread nicht dazu zwingen können, eine Ausnahme auszulösen, wenn er gerade dabei ist, etwas zu tun. –

0

Was wäre, wenn Sie c3p0 für Ihre dataSource verwenden würden? Es hat viele konfigurierbare Optionen und für verschrobene Datenbanken und Netzwerke zum Beispiel acquireRetryAttempts, acquireRetryDelay und breakAfterAcquireFailure.

0

Mit dem Schlüsselwort LOCAL wird der Gültigkeitsbereich von statement_timeout auf die aktuelle Transaktion beschränkt. Auf diese Weise wird die Zeitüberschreitung zurückgesetzt, wenn etwas schief geht (z. B. Zeitüberschreitung).

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