2008-11-17 9 views
26

Gibt es eine Möglichkeit, eine Transaktion vorzeitig abzubrechen? Sagen wir, ich habe einen Befehl an die Datenbank gesendet, der fünf Minuten läuft und nach vier möchte ich ihn abbrechen.Wie kann ich eine laufende JDBC-Transaktion abbrechen?

Definiert JDBC eine Möglichkeit, ein Signal "Stop, was auch immer Sie an dieser Verbindung tun" an die DB zu senden?

Antwort

28

Wie von James erwähnt, wird Statement.cancel() die Ausführung einer laufenden Anweisung (auswählen, aktualisieren, etc) abbrechen. Die JDBC-Dokumentation besagt ausdrücklich, dass Statement.cancel() sicher aus einem anderen Thread ausgeführt werden kann und schlägt sogar vor, sie in einem Zeitüberschreitungs-Thread aufzurufen.

Nachdem Sie die Anweisung abgebrochen haben, sind Sie immer noch dabei, die Transaktion rückgängig zu machen. Das ist nicht dokumentiert als sicher aus einem anderen Thread ausgeführt werden. Die Connection.rollback() sollte im Haupt-Thread geschehen, die alle anderen JDBC-Aufrufe erledigt. Sie können das behandeln, nachdem der abgebrochene Aufruf von Statement.execute ...() mit einer JDBCException abgeschlossen wurde (aufgrund des Abbrechens).

+1

Hier ist Orakel-spezifisches Verhalten beim Aufruf von 'Statement.cancel()': http://stackoverflow.com/a/659063/603516 – Vadzim

-5

Nein, Sie können es nicht mit JDBC Standard abbrechen.

Sie könnten versuchen, zu überprüfen, ob Ihr spezielles RDBMS eine Erweiterung definiert, um es zu unterstützen.

+4

Ich hatte Verkäufer mir das sagen lassen. Wenn ein bestimmter JDBC-Treiber Statement.cancel() nicht implementiert, handelt es sich um ein Problem der Implementierung. Es ist da und dokumentiert für diesen Anwendungsfall. –

12

Ich rate, was Sie tun möchten, ist Ihre Anwendung blockiert auf lange laufende Abfragen/Transaktionen zu verhindern. Zu diesem Zweck unterstützt JDBC das Konzept eines Abfragetimeouts. Sie können die Abfrage Timeout dies mit:

java.sql.Statement.setQueryTimeout(seconds) 

Und die SQLException durch die execute() Methode geworfen Griff durch die Transaktion (natürlich rollen zurück, dass nur funktionieren würde, wenn Sie auf false gesetzt haben autocommit und Ihre JDBC-Treiber unterstützt Statement.cancel()).

+0

Ich denke, dies ist ein besserer und einfacherer Ansatz, da es dem Laufstreifen ermöglicht, sich selbst zu reinigen, im Gegensatz zu einem Außengewinde (was immer eine neue Reihe von Problemen mit sich bringt). – Faustas

5

Überprüfen Sie Statement.cancel().

Verwandte Themen