Wie erkennt man genau, ob ein SQL Server-Job ausgeführt wird und den bereits ausgeführten Job bearbeitet?

9

Ich verwende derzeit Code wie diesen, um festzustellen, ob ein SQL-Server-Job ausgeführt wird. (Dies ist SQL Server 2005, alle SPs)

%Vor%

Dort gibt es keine Probleme, und im Allgemeinen funktioniert es gut.

Aber .... (immer ein aber)

Gelegentlich rufe ich dies auf, bekomme ein "Job läuft nicht" -Ergebnis zurück, an welchem ​​Punkt ich versuche, den Job über

zu starten %Vor%

und SQL wird zurückgeben, dass "SQLAgent den Auftrag nicht gestartet hat, weil er bereits eine ausstehende Anforderung hat".

Ok. Auch kein Problem. Es ist denkbar, dass ein kleines Fenster existiert, in dem der Zieljob gestartet werden kann, bevor dieser Code gestartet werden kann, aber nachdem er überprüft hat, ob er gestartet wurde. Allerdings kann ich das nur in einen try Catch einpacken und den Fehler einfach ignorieren, oder?

%Vor%

Hier ist das Problem.

9 mal von 10, das funktioniert ganz gut. Der SQL-Agent löst den Fehler aus, er wird abgefangen, und die Verarbeitung wird einfach fortgesetzt, da der Job bereits ausgeführt wird und kein Schaden entsteht.

Aber gelegentlich erhalte ich eine Meldung in der Jobhistorie-Ansicht (beachte den obigen Code, um zu erkennen, ob ein bestimmter Job ausgeführt wird und starte ihn, wenn er nicht von einem anderen Job ausgeführt wird), dass der Job fehlgeschlagen ist "SQLAgent hat das Starten des Jobs abgelehnt, da bereits eine Anforderung aussteht."

Natürlich ist das der genaue Fehler, den TRY CATCH behandeln soll!

Wenn das passiert, stirbt der ausführende Job einfach, aber nicht sofort von dem, was ich sagen kann, nur ziemlich nah. Ich habe die Holzfällerei überall hingelegt und es gibt keine Konsistenz. Einmal fehlgeschlagen, wird es an der Stelle a, das nächste Mal an der Stelle b. In einigen Fällen haben Platz A und Platz B nichts anderes als ein

%Vor%

dazwischen. Sehr eigenartig. Im Grunde scheint der Job kurzerhand abgelegt zu sein und alles, was im Job ausgeführt wird, wird + nicht + ausgeführt.

Wenn ich jedoch den "exec StartJob" entferne (oder ihn genau einmal aufgerufen habe, wenn ich weiß, dass der Zieljob nicht bereits ausgeführt werden kann), läuft alles perfekt und alle meine Verarbeitungen im Job laufen durch.

Der Grund dafür ist, dass ein Job unter anderem aufgrund eines Triggers gestartet wird. Wenn der Job bereits gestartet wurde, muss er nicht wirklich "neu gestartet" werden.

Wer hat jemals mit der Auftragsverarbeitung des SQL-Agenten auf ein solches Verhalten gestoßen?

BEARBEITEN: Der aktuelle Steuerungsfluss ist wie folgt:

  1. Zu einer Tabelle wechseln (aktualisieren oder einfügen) ...
  2. löst aus, welche Aufrufe ...
  3. auslösen
  4. ein gespeicherter proc, der ...
  5. aufruft
  6. sp_Start_Job welcher ...
  7. startet einen bestimmten Job, den ...
  8. ruft einen anderen gespeicherten Prozess (namens CheckQueue) auf, der ...
  9. führt einige Verarbeitungen durch und ...
  10. überprüft mehrere Tabellen und je nach Inhalt möglicherweise ...
  11. ruft sp_start_job in einem anderen Job auf, um einen zweiten, gleichzeitigen Job zu starten um die zusätzliche Arbeit zu verarbeiten (dieser zweite Job ruft auch den CheckQueue-Sproc auf) aber die zwei Aufrufe operieren auf völlig getrennten Datensätzen)
DarinH 02.05.2011, 19:02
quelle

3 Antworten

4

Hatten Sie zuerst Gelegenheit, sich einen Service Broker anzuschauen? Aus Ihrer Beschreibung klingt das, als ob Sie das wirklich wollen.

Der Unterschied wäre, statt einen Job zu starten, Ihre Daten in eine SB-Queue zu legen und SB Ihre Verarbeitungsprozedur asynchron und vollständig als Side-Step-Probleme mit bereits laufenden Jobs usw. aufzurufen. Es wird automatisch weitere Threads spawnen / beenden und die Nachfrage diktiert, es kümmert sich um Ordnung etc.

Hier ist eine gute (und vage verwandte) Anleitung. Ссылка

Nehmen wir an, dass Sie SB aus irgendeinem Grund nicht benutzen können (aber ernsthaft, tun Sie!).

Was ist mit der Verwendung der Context_info des Jobs spid?

  1. Ihr Job ruft einen Wrapper-Prozess auf, der jeden Schritt einzeln ausführt.
  2. Die erste Anweisung innerhalb des Wrapper-Prozesses ist

    %Vor%
  3. Wenn Ihr Prozess abgeschlossen ist (oder in Ihrem Catch-Block)

    %Vor%
  4. Wenn Sie Ihren Job aufrufen, tun Sie Folgendes:

    %Vor%

Wenn Ihr Wrapper Proc beendet wird oder die Verbindung geschlossen wird, geht Ihre context_info verloren.

Sie können auch eine globale temporäre Tabelle verwenden (d. h. ## JobStatus) Sie verschwinden, wenn alle Spids, die auf sie verweisen, getrennt werden oder wenn sie explizit gelöscht werden.

Nur ein paar Gedanken.

    
Code Magician 03.08.2011, 17:35
quelle
2

Ich habe eine Abfrage, die mir die laufenden Jobs gibt, vielleicht kann es dir helfen. Es hat für mich funktioniert, aber wenn Sie einen Fehler finden, lassen Sie es mich wissen, ich werde versuchen, es zu korrigieren. Prost.

%Vor%     
marcello miorelli 27.09.2014 14:52
quelle
-3

Um mit einem bereits laufenden Job fertig zu werden: 1. Öffnen Sie den Task-Manager 2. Überprüfen Sie, ob ein Prozess mit ImageName "DTExec.exe" ausgeführt wird 3. Wenn der Prozess läuft und es sich um den problematischen Job handelt, führen Sie "Prozess beenden" aus.

    
Menahem 10.07.2013 11:16
quelle