Willkommen auf myCSharp.de! Anmelden | kostenlos registrieren
 | Suche | FAQ

Hauptmenü
myCSharp.de
» Startseite
» Forum
» Suche
» Regeln
» Wie poste ich richtig?

Mitglieder
» Liste / Suche
» Wer ist online?

Ressourcen
» FAQ
» Artikel
» C#-Snippets
» Jobbörse
» Microsoft Docs

Team
» Kontakt
» Cookies
» Spenden
» Datenschutz
» Impressum

  • »
  • Community
  • |
  • Diskussionsforum
Oracle SQL Abfrage abbrechen
Net_Hans
myCSharp.de - Member



Dabei seit:
Beiträge: 70

Themenstarter:

Oracle SQL Abfrage abbrechen

beantworten | zitieren | melden

Hallo,

ich habe vor einen Datenbankabfrage durchzuführen, welche mehrere Minuten dauern kann. Da dieses in einem Windowsservice laufen soll, muss ich unter bestimmten Bedingungen (stoppen vom Service etc.) das Programm schnellst möglich stoppen können. Wie kann ich im folgendem Coldeauszug den Abbruch erkennen und die SQL Abfrage abzubrechen.?

using (OracleConnection connection = new OracleConnection())
                {
                    connection.ConnectionString = connectionString;
                    connection.Open();
                    OracleCommand command = connection.CreateCommand();
                    OracleDataReader reader;
                    string sql;
                    sql = "SELECT * FROM TESTVIEW ";


                    command.CommandText = sql;
                    reader = command.ExecuteReader();
                    ...

Das Abbrechen wird in Form von einer Variable vorliegen ... sprich wenn zB. die Variable sys_cancel auf true gesetzt wird soll die SQL Abfrage stoppen.

Gibt es da eine Lösung?

Danke für eure Hilfe
mfG Hans
private Nachricht | Beiträge des Benutzers
chanderegg
myCSharp.de - Member



Dabei seit:
Beiträge: 101
Herkunft: Solothurn CH

beantworten | zitieren | melden

Ich würd dir vorschlagen das ganze mit einer Transaction zu machen


using (OracleConnection myConnection = new OracleConnection())
                {
                    myConnection = AGB70.PABS.Common.Var.gblDBInfo.GetDbConnection();
            myConnection.Open();

            //Definiert den Start einer Übertragung
            myTransaction = myConnection.BeginTransaction(); //vielleicht noch isolationslevel hinzufügen

            //Erstellt ein Commandobjekt, welches die SQL-Statements ausführt
            myCommand = AGB70.PABS.Common.Var.gblDBInfo.GetDbCommand();
            mytCommand.Connection = myConnection;
            mytCommand.Transaction = myTransaction;
}

so kannst du schlussendlich mit rollback alles rückgängig machen


if (sys_cancel)
{
 myTranscation.Rollback();
}
ps. am schluss nicht den commit vergessen
private Nachricht | Beiträge des Benutzers
tom-essen
myCSharp.de - Experte

Avatar #avatar-2140.png


Dabei seit:
Beiträge: 1.815
Herkunft: NRW

beantworten | zitieren | melden

Hallo!

Man könnte auch alles in einen separaten Thread packen, und diesen dann bei bedarf beenden. Dadurch wird auch die Abfrage beendet.
Nobody is perfect. I'm sad, i'm not nobody
private Nachricht | Beiträge des Benutzers
Net_Hans
myCSharp.de - Member



Dabei seit:
Beiträge: 70

Themenstarter:

beantworten | zitieren | melden

Hallo,

danke schon mal für die ersten vorschläge.


@chanderegg
Das mit der Transaktion habe ich glaube nicht 100% verstanden. Da ich nur Abfragen (SELECT) verarbeite, werde ich kein Rollback benötigen.

Mein Problem ist viel mehr das das die Abfrage alleine schon mehrere Minuten benötigt.



@tom-essen
Die Idee mit dem separaten Theader hatte ich auch schon, aber die Idee wollte ich nicht weiter verfolgen, da das ja bedeuten würde, das ich die Oracle Verbindung "abschieße" und ich so eventuell Fehler und Deadlocks erzeuge könnte.




Kann man so einen hartes abschießen nicht irgendwie verhindern?

Bei meinem Datenbank Tool (Toad) kann man die SELECT Anweisungen auch schön sauber abbrechen.

mfG Hans
private Nachricht | Beiträge des Benutzers
witte
myCSharp.de - Member



Dabei seit:
Beiträge: 955

beantworten | zitieren | melden

Hallo,

Du könntest Deine sid (session instance identifier) und die serial# vor der lang laufenden Anfrage auslesen (v$session?) und mit ALTER SYSTEM KILL SESSION in einem anderen Thread beenden,.


http://www.wer-weiss-was.de/theme165/article1867698.html
private Nachricht | Beiträge des Benutzers
Net_Hans
myCSharp.de - Member



Dabei seit:
Beiträge: 70

Themenstarter:

beantworten | zitieren | melden

Hallo witte,

wenn ich mir das richtig durchgelesen habe, müsste ich um sicher zu stellen, das die Session gekillt wird wirklich hart killen mit diesem -9. ... hmm so toll finde ich das aber auch nicht, meinem Programm einfach die Oracle Session weg zu nehmen.

Es muss doch möglich sein, die Transaktion sauber zu beenden (auf einem dafür vorgesehenen Weg) ohne ein kill oder ähnliches.

So nach dem Motto, cancel Transaktion xy ... und Oracle bricht dann kontrolliert die Anfrage ab.

Ich bin ganz ehrlich von diesem "Ach beenden / killen wir es einfach hart ... wird schon nichts passieren" halte ich nicht alt so viel ... Am Ende gibt das nur Probleme.
private Nachricht | Beiträge des Benutzers
witte
myCSharp.de - Member



Dabei seit:
Beiträge: 955

beantworten | zitieren | melden

Zitat von Net_Hans
Ich bin ganz ehrlich von diesem "Ach beenden / killen wir es einfach hart ... wird schon nichts passieren" halte ich nicht alt so viel ... Am Ende gibt das nur Probleme.
Das ist quatsch. Ein Serversystem taugt nichts wenn es durch solche Abbrüche in die knie zwingen läßt. Wäre ja ne prima DOS-Attacke.
Aber Du sollst ja nicht den OS-Prozeß killen sondern die Oracle-Session. Ich glaube nicht dass das auf Transaktionsebene geht. Dein TOAD wird es wahrscheinlich auch so handhaben: die SID aus der ersten Transaktion vorher auslesen und in einer zweiten Verbindung abbrechen. Du kannst ja mal mit einem Profiler/Wireshark den Datentransfer mitschneiden und schauen was bei TOAD passiert.
private Nachricht | Beiträge des Benutzers
Xynratron
myCSharp.de - Member



Dabei seit:
Beiträge: 1.177

beantworten | zitieren | melden

huhu,

eine Transaktion abzubrechen schadet keinem DB-System. Genau dafür sind Transaktionen da. Auch das beenden einer Verbindung sorgt in dem Fall für einen Rollback der Transaktion. Sogar bei einem Stromausfall wird im Normalfall beim wiederanlaufen der DBs geguckt, ob man noch ein paar transaktionen, welche nicht fertig waren, wieder rückgängig machen muss.

Für dein Problem gibts aber IDbCommand.Cancel(). Dann würde ich aber auch zusätzlich die BeginXXX-Methoden verwenden um das ganze asynchron zu halten.

:-)

xynratron
Herr, schmeiss Hirn vom Himmel - Autsch!
Zitat von herbivore
Die Erfahrung zeigt immer wieder, dass viele Probleme sich in Luft auslösen, wenn man sich den nötigen Abstand bzw. Schlaf gönnt.
private Nachricht | Beiträge des Benutzers
Net_Hans
myCSharp.de - Member



Dabei seit:
Beiträge: 70

Themenstarter:

beantworten | zitieren | melden

Hallo,

das mit der IDbCommad.Cancel() klingt doch gut, kann mir dazu eventuell mal ein beispiel geben ... denn ich hänge bei dieser Idee an dem Punkt, wo ich der Meinung bin, das mein Programm beim

reader = command.ExecuteReader();

solange wartet, bis dieser Befehl durch gelaufen ist. und somit kann ich ja das Cancel nicht durchführen oder?
private Nachricht | Beiträge des Benutzers
FZelle
myCSharp.de - Experte



Dabei seit:
Beiträge: 9.954

beantworten | zitieren | melden

Weshalb dir Xynratron auch gleich geraten hat die Asynchronen Beginxxx Funktionen zu nutzen.
private Nachricht | Beiträge des Benutzers
Net_Hans
myCSharp.de - Member



Dabei seit:
Beiträge: 70

Themenstarter:

beantworten | zitieren | melden

Achso ... den Befehl gibt es wirklich ... ich dachte das mit dem xxx war mehr ein Beispiel ... ist das sowas wie der Backgroundworker?
private Nachricht | Beiträge des Benutzers