2010-03-03 4 views
9

Ich erstelle eine RESTful-API, die auf die Datenbank zugreifen muss. Ich benutze Restish, Oracle und SQLAlchemy. Ich versuche jedoch, meine Frage so allgemein wie möglich zu formulieren, ohne Restish oder andere Web-APIs zu berücksichtigen.Festlegen der Zeitüberschreitung bei der Datenbankverbindung in Python

Ich möchte in der Lage sein, ein Timeout für eine Verbindung festzulegen, die eine Abfrage ausführt. Auf diese Weise wird sichergestellt, dass Abfragen mit langer Laufzeit abgebrochen und die Verbindung verworfen (oder wiederverwendet) wird. Dieses Abfragetimeout kann ein globaler Wert sein, dh ich muss es nicht nach Abfrage oder Verbindungserstellung ändern.

den folgenden Code Gegeben:

import cx_Oracle 
import sqlalchemy.pool as pool 

conn_pool = pool.manage(cx_Oracle) 
conn = conn_pool.connect("username/[email protected]") 
conn.ping() 

try: 
    cursor = conn.cursor() 
    cursor.execute("SELECT * FROM really_slow_query") 
    print cursor.fetchone() 
finally: 
    cursor.close() 

Wie kann ich den obigen Code ändern auf eine Abfrage-Timeout zu setzen? Wird diese Zeitüberschreitung auch für die Verbindungserstellung gelten?

Dies ist ähnlich wie die Methode setQueryTimeout (int seconds) von java.sql.Statement in Java.

Dank

+0

Hallo, ich sehe, dass keine aus Antworten akzeptiert wird hast du eine andere Lösung dafür gefunden? – Ib33X

+0

Nein, ich konnte diese Arbeit nicht machen. Die bisher vorgeschlagenen Lösungen funktionieren einfach nicht. – oneself

+0

Warum funktioniert 'conn.cancel()' nicht? Was passiert, wenn Sie Dmitrys Lösung ausprobieren? – alldayremix

Antwort

0

Sie bei der Einrichtung PROFILE s in Oracle aussehen könnte die Anfragen nach einer bestimmten Anzahl von logical_reads_per_call und/oder cpu_per_call

-3

Timing-Out mit dem Systemalarm

hier zu beenden wie man das Betriebssystem Timout verwendet, um dies zu tun. Es ist generisch und funktioniert für andere Dinge als Oracle.

+0

Dies scheint nicht zu funktionieren. Oracle wird nicht unterbrochen. – oneself

+0

Natürlich wird Oracle (auf dem Server) nicht unterbrochen - Sie sagten, Sie wollten "die langwierige Abfrage abbrechen", was bedeutet, dass Sie einfach auf die Antwort warten. Wenn Sie Oracle tatsächlich dazu bringen wollen, die Abfrage nicht mehr auszuführen - das ist eine ganz andere Sache und nicht so einfach - müssten Sie die Sitzung auf dem Server "beenden" ... –

+1

Was ich sagen wollte, ist die Abfrage läuft weiterhin ununterbrochen auf dem Client. – oneself

11

für die Abfrage können Sie auf Timer und conn.cancel() aufrufen.

etwas in diese Richtung:

t = threading.Timer(timeout,conn.cancel) 
t.start() 
cursor = conn.cursor() 
cursor.execute(query) 
res = cursor.fetchall() 
t.cancel() 
+0

Das funktioniert so gut, danke! So kann ich meine langwierigen Anfragen beenden. – Emmanuel

3

In Linux siehe /etc/oracle/sqlnet.ora,

sqlnet.outbound_connect_timeout= value

auch Möglichkeiten:

tcp.connect_timeout und sqlnet .expire_time, viel Glück!

+0

Ich denke, das ist für die Verbindung, nicht Anweisung Ausführung. – Glyph

+0

Es ist eine funktionierende Lösung, versuche es;) – BetarU