Ich habe eine Java JDBC-Anwendung, die gegen eine Oracle 10g-Datenbank läuft. Ich richte eine PreparedStatement ein, um eine Abfrage auszuführen, und rufe dann ps.executeQuery () auf, um sie auszuführen. Gelegentlich dauert die Abfrage sehr lange und ich muss sie löschen. Ich habe einen anderen Thread Zugriff auf das PreparedStatement-Objekt, und cancel () darauf aufrufen.
Meine Frage ist, tötet dies tatsächlich die Abfrage in der Datenbank? Oder trennt es es einfach vom Client, und die Abfrage läuft noch irgendwo im Inneren von Oracle?
Danke!
Die Antwort lautet, dass es sich um ein Problem der Qualität der Implementierung handelt. Wenn Sie sich das javadoc für Statement ansehen .cancel () sagt, dass es passieren wird, "wenn sowohl das DBMS als auch die Treiberunterstützung eine SQL-Anweisung abbrechen".
Nach meiner Erfahrung mit verschiedenen Versionen von Oracle JDBC-Treibern scheint Statement.cancel () das zu tun, was Sie wollen. Die Abfrage scheint nicht mehr ausgeführt zu werden, wenn sie abgebrochen wird.
Bitte beachten Sie, dass das, was ich unten sage, auf Beobachtungen und Schlussfolgerungen von Oracle im Gebrauch basiert und nicht auf einem tiefen Verständnis von Oracles Interna basiert. Nichts davon sollte als maßgebend angesehen werden.
Was ninesided in ihrem ersten Absatz gesagt ist, ist richtig. Beachten Sie jedoch den vorgeschlagenen Test. Nicht alle Oracle-Abfragen mit langer Laufzeit sind gleich. Es scheint, dass Abfragen über zwei Phasen ausgewertet werden: erstens eine Phase, die genügend Daten kombiniert, um zu wissen, wie die Zeilen in der richtigen Reihenfolge zurückgegeben werden, und zweitens eine Phase, die die Zeilen zurückgibt, die die Lücken füllen, die sie nicht berechnet hat erste Phase. Die Aufteilung der Arbeit zwischen den beiden Phasen wird auch von den Einstellungen des kostenbasierten Optimierers beeinflusst. z.B. Erste Zeilen vs Alle Zeilen.
Wenn sich die Abfrage jetzt in Phase 1 befindet, scheint die Abbruchanforderung bestenfalls in der Warteschlange zu sein, um am Ende von Phase 1 angewendet zu werden, was bedeutet, dass die Abfrage weiterläuft.
In Phase 2 werden Zeilen in Bündeln zurückgegeben, und nach jedem Bündel kann der Befehl zum Abbrechen wirksam werden. Wenn der Treiber den Befehl unterstützt, führt die Abbruchanforderung dazu, dass die Abfrage beendet wird.
Die Spezifikation für den JDBC-Befehl "Abbrechen" scheint nicht zu sagen, was passieren soll, wenn die Abfrage nicht beendet wird. Daher kann der Befehl auf die Bestätigung des Kills warten, oder er kann eine Zeitüberschreitung aufweisen und mit der noch laufenden Abfrage zurückkehren / p>
Es hängt von dem Treiber ab, den Sie verwenden. Sowohl der Treiber als auch die Datenbank müssen die Stornierung einer Anweisung unterstützen, damit sie wie gewünscht funktioniert. Oracle unterstützt diese Funktion, aber Sie müssen mehr über den spezifischen Treiber wissen, den Sie verwenden, um sicher zu sein.
Alternativ können Sie einen einfachen Test ausführen, indem Sie nach dem Einleiten und Abbrechen einer lang laufenden Abfrage in die Datenbank schauen.