Timeout für die OracleDataReader.Read-Methode

8

Die ODP.NET OracleCommand-Klasse verfügt über eine CommandTimeout-Eigenschaft, mit der ein Zeitlimit für die Ausführung eines Befehls erzwungen werden kann. Diese Eigenschaft scheint in Situationen zu funktionieren, in denen der CommandText eine SQL-Anweisung ist. Der Beispielcode wird verwendet, um diese Eigenschaft in Aktion zu veranschaulichen. In der ersten Version des Codes wird CommandTimeout auf Null festgelegt, sodass ODP.NET kein Zeitlimit erzwingt.

%Vor%

Beispielausgabe für den obigen Code ist unten gezeigt:

%Vor%

Wenn ich CommandTimeout auf 3 ändere ...

%Vor%

... und dann den gleichen Code ausführen, erzeugt die folgende Ausgabe:

%Vor%

Das Aufrufen einer gespeicherten Prozedur, die einen Ref-Cursor zurückgibt, ist jedoch eine andere Sache. Betrachten Sie den folgenden Testprozess (nur zu Testzwecken):

%Vor%

Der folgende Beispielcode kann zum Aufrufen des gespeicherten Proc verwendet werden. Beachten Sie, dass es CommandTimeout auf einen Wert von 3 setzt.

%Vor%

Beispielausgabe vom obigen Code ist unten gezeigt:

%Vor%

Beachten Sie, dass die Ausführungszeit sehr kurz ist (34 ms) und dass keine Timeout-Ausnahme ausgelöst wurde. Die Leistung, die wir hier sehen, liegt daran, dass die SQL-Anweisung für einen Ref-Cursor erst beim ersten Aufruf der OracleDataReader.Read-Methode ausgeführt wird. Wenn der erste Read () - Aufruf ausgeführt wird, um den ersten Datensatz aus dem Refcursor zu lesen, ist der Leistungseinbruch von der lang laufenden Abfrage aufgetreten.

Das von mir veranschaulichte Verhalten bedeutet, dass die OracleCommand.CommandTimeout-Eigenschaft nicht zum Abbrechen einer lang andauernden Abfrage verwendet werden kann, die einem ref-Cursor zugeordnet ist. Mir ist keine Eigenschaft in ODP.NET bekannt, die verwendet werden kann, um die Ausführungszeit eines ref-Cursors SQL in dieser Situation zu begrenzen. Jeder hat irgendwelche Vorschläge, wie die Ausführung einer lang laufenden ref Cursor SQL-Anweisung nach einer gewissen Zeit kurzgeschlossen werden könnte?

    
dnickels 17.05.2013, 16:39
quelle

2 Antworten

4

Hier ist die Lösung, mit der ich letztendlich gegangen bin. Es ist nur eine Erweiterungsmethode für die OracleDataReader-Klasse. Diese Methode hat einen Timeout-Wert und eine Callback-Funktion als Parameter. Die Callback-Funktion wäre typischerweise (wenn nicht immer) OracleCommand.Cancel.

%Vor%

Hier ist ein Beispiel, wie es verwendet werden kann.

%Vor%

Und hier ist ein Beispiel für die Ausgabe.

%Vor%     
dnickels 06.08.2013, 21:23
quelle
1

Es scheint, dass Sie nicht der Erste sind, der fragt: Ссылка

Sie könnten innerhalb der Schleife über den Leser überwachen. Lesen Sie die verstrichene Zeit und verlassen Sie die Schleife. Das ist schön und einfach, aber natürlich wird es nur möglich sein, nach einem potenziell langen Anruf zu beenden, beendet zu beenden.

Ihre beste Wette wäre wahrscheinlich, die Schleife innerhalb einer Aufgabe in einem separaten Thread auszuführen, sie zu überwachen und dann cmd.Cancel für den ursprünglichen Thread aufzurufen:

%Vor%

Es ist erwähnenswert, dass die Ausnahme ORA-01013 auf den Arbeitsthread und nicht auf den Thread, der OracleCommand.Cancel aufruft, geworfen wird.

    
b_levitt 20.05.2013 20:13
quelle

Tags und Links