Ich habe mir das heute angetan und das Problem komplett analysiert.
Mit einem Trace der SQL Anfragen konnte ich nachvollziehen, dass der WSUS-Serverdienst einen ganzen Satz von Funktionen über RPC (EXEC Befehl auf dem SQL-Server) beim starten des Diensts aufruft.
Alle Funktionen außer einer, werden auch wieder beendet. Die Funktion, die nicht beendet wird und den SQL Server komplett auslastet heißt "spResetStateMachineAndReEvaluate".
Das ist die Funktion in der die gesamte Abarbeitung des Aufräumvorgangs läuft.
Und genau in dieser Funktion lässt sich sehen, dass lokal in der Funktion ein SQL Cursor verwendet wird, der im wesentlichen alle Zeilen der Tabelle dbo.tbRevision abarbeitet.
Ein Herunterfahren des Systems bewirkt dann natürlich, dass dieser lokale Cursor wieder zurückgesetzt wird.
Hier der Codeausschnitt:
DECLARE #cur CURSOR LOCAL FAST_FORWARD FOR
SELECT RowID FROM dbo.tbRevision WHERE State <> 1
OPEN #cur
FETCH #cur INTO @revisionRowID
WHILE @@ERROR = 0 AND @@FETCH_STATUS = 0
BEGIN
SET @storedProcedureToExecute = NULL
EXEC @retcode = dbo.spFireStateMachineEventEx 'RevisionStateMachine', @revisionRowID, 'ResetRevision', @storedProcedureToExecute OUTPUT, @stateMachineIDForSP OUTPUT, @rowIDForSP OUTPUT, @oldStateIDForSP OUTPUT, @eventIDForSP OUTPUT, @newStateIDForSP OUTPUT
IF @@ERROR <> 0 OR @retcode <> 0
BEGIN
CLOSE #cur
DEALLOCATE #cur
SET @errorMessage = 'spResetStateMachineAndReEvaluate got failure from spFireStateMachineEvent for parameters: @StateMachineName = RevisionStateMachine, @RowID = ' + CONVERT(NVARCHAR(40), @revisionRowID) + ', @EventName = ResetRevision'
RAISERROR(@errorMessage, 16, -1)
RETURN 1
END
IF @storedProcedureToExecute IS NOT NULL
BEGIN
EXEC @retcode = @storedProcedureToExecute @stateMachineIDForSP, @rowIDForSP, @oldStateIDForSP, @eventIDForSP, @newStateIDForSP
IF @@ERROR <> 0 OR @retcode <> 0
BEGIN
CLOSE #cur
DEALLOCATE #cur
SET @errorMessage = dbo.fn_FormatError(@storedProcedureToExecute, @stateMachineIDForSP, @rowIDForSP, @oldStateIDForSP, @eventIDForSP, @newStateIDForSP)
RAISERROR(@errorMessage, 16, -1)
RETURN 1
END
END
FETCH NEXT FROM #cur INTO @revisionRowID
END
Für jeden Eintrag in der Tabelle dbo.tbRevision (also jede Update-Revision) existiert ein eigener Zustand. Jede Revision befindet sich in ihrem eigenen Zustand in der State-Machine des Update-Handlings.
Die Abarbeitung in der Schleife bewirkt ein Überprüfen und Aktualisieren jedes einzelnen Zustands und ggf. Download von Dateien.
Und jetzt zur Eintrittsbedingung, die dafür sorgt, dass der Vorgang überhaupt läuft.
IF NOT EXISTS (SELECT * FROM dbo.tbSingletonData WHERE ResetStateMachineNeeded = 1)
BEGIN
RETURN 0
END
Das ist genau die Angabe aus dem Lösungsvorschlag im Tech Net.
Ich habe es gleich mal ausprobiert ... und siehe da, es funktioniert