none
Benachrichtigungen mit SqlDependency funktionieren nicht RRS feed

  • Frage

  • Hallo,

    ich experimentiere gerade mit SqlDependency, habe dabei aber das Problem, dass ich keine Benachrichtigungen bei Änderungen in der Datenbank erhalte.

    Die Datenbank wurde von dem Windows-Nutzer angelegt, der auch die Anwendung ausführt. In der Datenbank gibt es eine Tabelle Persons mit den Feldern Id und Name.

    SqlDependency.Start(connectionString);
    using (var connection = new SqlConnection(connectionString))
    {
        connection.Open();
    
        var commandText = "SELECT Id, Name FROM dbo.Persons;";
        var command = new SqlCommand(commandText, connection);
    
        var dependeny = new SqlDependency(command);
        dependeny.OnChange += (sender, e) => Console.WriteLine("Something changed.");
    
        command.ExecuteReader();
    
        var changeSomethingCmd = new SqlCommand("UPDATE Persons SET Name = 'Alice' WHERE Id = 1;", connection);
        changeSomethingCmd.ExecuteNonQuery();
    }

    Da von den Änderungen in der Tabelle auch die SQL-Abfrage betroffen ist, müsste doch das OnChange-Event gefeuert werden? Allerdings passiert bei mir auch nach langer Wartezeit nichts.

    Die erforderlichen Permissions sind vorhanden. Ich verwende SQL Server Developer 2017, die Anwendung läuft mit .NET Framework 4.6.1.

    Wo könnte mein Fehler liegen? Vielen Dank im Voraus.

    Viele Grüße

    Florian

    • Bearbeitet Flogex Dienstag, 20. Februar 2018 13:59
    Dienstag, 20. Februar 2018 13:57

Antworten

  • Hallo,

    ich habe die ganzen Benachrichtigungen, die nicht bei mir angekommen sind, in sys.transmission_queue gefunden. Im Feld transmission_status stand:

    "An exception occurred while enqueueing a message in the target queue. Error: 15404, State: 19. Could not obtain information about Windows NT group/user 'X\user', error code 0x54b.".

    Mithilfe dieses Threads konnte ich dann das Problem lösen: Could not obtain information about Windows NT group/user.

    Wie empfohlen, habe ich "clr enabled" auf 1 gesetzt und die Benachrichtigungen sind angekommen.

    Da ich erst sei 2 Tagen mit SQL Server arbeite, habe ich keine Ahnung, was der Fehler bedeutet und was geändert wird, wenn die CLR aktiviert wird. Das heißt es nun, herauszubekommen. :)

    Nochmal vielen Dank für eure Antworten.

    Viele Grüße

    Mittwoch, 21. Februar 2018 11:53

Alle Antworten

  • Hallo Florian,

    für die Benachrichtigung wir der SQL Server Service Broker verwendet, das ist eine Einstellung auf Datenbank-Ebene und im Standard abgeschaltet; hast Du den SB für die verwendete Datenbank aktiviert?

    Kannst Du prüfen mit

    select name, is_broker_enabled
    from sys.databases

    und aktivieren mit

    ALTER DATABASE [DeineDatenbank] SET ENABLE_BROKER WITH NO_WAIT;


    Olaf Helper

    [ Blog] [ Xing] [ MVP]

    Dienstag, 20. Februar 2018 17:27
  • Hallo Olaf,

    vielen Dank für deine Antwort.

    Ja, den Service Broker habe ich aktiviert. Leider funktioniert es trotzdem nicht.

    • Bearbeitet Flogex Dienstag, 20. Februar 2018 19:43
    Dienstag, 20. Februar 2018 19:42
  • Hallo,

    ich hatte mal dieses PoSh Skript geschrieben Query Notification for Monitoring Data Changes, das funktioniert und den einzigen Unterschied, den ich sehe, ist das ich keinen Reader geöffnet habe, sondern beim zu überwachenden Command ExecuteNonQuery verwendet habe.


    Olaf Helper

    [ Blog] [ Xing] [ MVP]

    Mittwoch, 21. Februar 2018 06:22
  • Wenn man die Doku liest bedeutet dies, dass die Überwachung auf einer Verbindung gestartet wird.

    Nun findet bei dir der Update aber auf derselben Verbindung wie die Überwachung statt, dadurch wird der Notify wahrscheinlich blockiert.
    Es heißt ja auch, dass fremde Veränderungen überwacht werden und dies passiert wohl mit separaten Verbindungen.

    Wenn man sich dann die Syntax ansieht, so bedeutet das eigentlich, dass der Reader oder auch NonQuery nun geblockt wird und auf das Ereignis wartet.

    Der nachfolgende Update wird somit gar nicht erst erreicht.
    Wenn der Reader nämlich fertig würde und der Using-Bloch endet, wird die verbindung nämlich getrennt (Dispose), so dass die Überwachung beendet wäre.

    Demnach müsste eine Überwachung auch in einem eigenen Tread passieren.

    Hast du mal den Debugger bemüht?

    Mittwoch, 21. Februar 2018 07:54
  • @Olaf Ja, und mit einem Reader sollte es auch funktionieren. Zumindest wird auch einer in der Dokumentation verwendet.

    @bfuerchau Danke für den Hinweis. Ich habe das Beispiel jetzt so umgebaut, dass für das Update eine eigene Verbindung genutzt wird. Dafür habe ich mir eine WPF-Anwendung gebastelt, wo über ein paar Buttons die SqlDependency gestartet, die Tabelle geupdated und die SqlDependency wieder gestoppt werden kann. Der Quellcode ist hier zu finden: https://github.com/Flogex/SqlDependencyTest. Eine Benachrichtigung bei Änderungen erhalte ich aber weiterhin nicht. Vielleicht ist es euch möglich, das Problem zu reproduzieren?

    Ich glaube nicht, dass die Überwachung in einem eigenen Thread stattfinden muss. Soweit ich das verstanden habe, wird mit SqlDependency.Start() eine eigene SqlConnection aufgebaut, sodass die Benachrichtigung auch ankommt, wenn die andere Connection geschlossen wird.

    Ich habe noch gelesen, dass man die Berechtigungen GRANT RECEIVE ON QueryNotificationErrorsQueue und GRANT SEND ON SERVICE:://theservice benötigt. Die dürften aber beim DBO schon vorhanden sein, oder?

    Viele Grüße

    • Bearbeitet Flogex Mittwoch, 21. Februar 2018 09:45
    Mittwoch, 21. Februar 2018 09:35
  • Hallo,

    ich habe die ganzen Benachrichtigungen, die nicht bei mir angekommen sind, in sys.transmission_queue gefunden. Im Feld transmission_status stand:

    "An exception occurred while enqueueing a message in the target queue. Error: 15404, State: 19. Could not obtain information about Windows NT group/user 'X\user', error code 0x54b.".

    Mithilfe dieses Threads konnte ich dann das Problem lösen: Could not obtain information about Windows NT group/user.

    Wie empfohlen, habe ich "clr enabled" auf 1 gesetzt und die Benachrichtigungen sind angekommen.

    Da ich erst sei 2 Tagen mit SQL Server arbeite, habe ich keine Ahnung, was der Fehler bedeutet und was geändert wird, wenn die CLR aktiviert wird. Das heißt es nun, herauszubekommen. :)

    Nochmal vielen Dank für eure Antworten.

    Viele Grüße

    Mittwoch, 21. Februar 2018 11:53
  • CLR (Common Language Runtime) steht i.W: für die .NET-Integration. Da du ja per .NET-Verbindung auf Ereignisse des SQL-Servers wartest, wird dieser dies wohl über Aufrufe der .NET-Runtime realisieren. Daher wohl die Aktivierung derselben.
    Mittwoch, 21. Februar 2018 11:57