[Gelöst] MS SQL : ENABLE_BROKER ( c# : SqlDependency )



  • Hallo Forum,

    Mittels SqlDependency-Class ist es möglich sich über Änderungen in einer Tabelle
    informieren zu lassen. Voraussetzung dafür ist, dass für die Datenbank "ENABLE_BROKER"
    gesetzt ist.

    ALTER DATABASE [<db_name>] SET  ENABLE_BROKER
    

    Diese Beispiel:
    http://www.codeproject.com/Articles/12335/Using-SqlDependency-for-data-change-events

    konnte zunächst erfolgreich getestet werden.

    Im zweiten Schritt beginnen nun die Probleme. Auf eine bestehende Datenbank
    sollte "... SET ENABLE_BROKER" ausgeführt werden. Dieser Vorgang dauerte allerdings "ewig"
    und konnte nur abgebrochen werden.

    Das Verhalten trat nicht nur bei mir auf:
    http://stackoverflow.com/questions/2758976/enabling-service-broker-in-sql-server-2008

    Lösung:

    ALTER DATABASE [DBNAME] SET ENABLE_BROKER WITH ROLLBACK IMMEDIATE
    

    Diese Anweisung wird zwar nun erfolgreich ausgeführt, jedoch funktioniert das
    obige Beispiel ( nach Anpassung von DB-Name und Statement ) nicht mehr ...

    Lösche ich meine Datenbank und erstelle sie neu kann im Anschluss im SQL-Script

    ALTER DATABASE [<db_name>] SET ENABLE_BROKER

    stehen und wird ohne zu blockieren erfolgreich ausgeführt.

    Im Anschluss funktioniert auch mein angepasstes Beispiel wieder.

    Frage ist nun ob die Benachrichtigung über eine Tabellenänderung ausschließlich
    von ENABLE_BROKER abhängt oder noch mehr notwendig ist, was übersehen wurde.

    Ist ENABLE_BROKER nicht gesetzt, erzeugt das im Beispiel eine Exception bei der
    Zeile : SqlDependency.Start(m_ConnectionString);

    Ist es gesetzt mit
    ALTER DATABASE [<db_name>] SET ENABLE_BROKER
    oder
    ALTER DATABASE [<db_name>] SET ENABLE_BROKER WITH ROLLBACK IMMEDIATE

    erscheint keine Exception.

    Edit:

    Das vollständige Script zum Erzeugen der Datenbank

    /****** Object:  Database [dbTest]    Script Date: 11/18/2005 13:55:20 ******/
    CREATE DATABASE [dbTest] ON  PRIMARY 
    ( NAME = N'dbTest', FILENAME = N'D:\db\dbTest.mdf' , SIZE = 5120KB , MAXSIZE = UNLIMITED, FILEGROWTH = 1024KB )
     LOG ON 
    ( NAME = N'dbTest_log', FILENAME = N'D:\db\dbTest_log.ldf' , SIZE = 1536KB , MAXSIZE = 2048GB , FILEGROWTH = 10%)
     COLLATE SQL_Latin1_General_CP1_CI_AS
    GO
    EXEC dbo.sp_dbcmptlevel @dbname=N'dbTest', @new_cmptlevel=90
    GO
    IF (1 = FULLTEXTSERVICEPROPERTY('IsFullTextInstalled'))
    begin
    EXEC [dbTest].[dbo].[sp_fulltext_database] @action = 'disable'
    end
    GO
    ALTER DATABASE [dbTest] SET ANSI_NULL_DEFAULT OFF 
    GO
    ALTER DATABASE [dbTest] SET ANSI_NULLS OFF 
    GO
    ALTER DATABASE [dbTest] SET ANSI_PADDING OFF 
    GO
    ALTER DATABASE [dbTest] SET ANSI_WARNINGS OFF 
    GO
    ALTER DATABASE [dbTest] SET ARITHABORT OFF 
    GO
    ALTER DATABASE [dbTest] SET AUTO_CLOSE OFF 
    GO
    ALTER DATABASE [dbTest] SET AUTO_CREATE_STATISTICS ON 
    GO
    ALTER DATABASE [dbTest] SET AUTO_SHRINK OFF 
    GO
    ALTER DATABASE [dbTest] SET AUTO_UPDATE_STATISTICS ON 
    GO
    ALTER DATABASE [dbTest] SET CURSOR_CLOSE_ON_COMMIT OFF 
    GO
    ALTER DATABASE [dbTest] SET CURSOR_DEFAULT  GLOBAL 
    GO
    ALTER DATABASE [dbTest] SET CONCAT_NULL_YIELDS_NULL OFF 
    GO
    ALTER DATABASE [dbTest] SET NUMERIC_ROUNDABORT OFF 
    GO
    ALTER DATABASE [dbTest] SET QUOTED_IDENTIFIER OFF 
    GO
    ALTER DATABASE [dbTest] SET RECURSIVE_TRIGGERS OFF 
    GO
    ALTER DATABASE [dbTest] SET  ENABLE_BROKER 
    GO
    ALTER DATABASE [dbTest] SET AUTO_UPDATE_STATISTICS_ASYNC OFF 
    GO
    ALTER DATABASE [dbTest] SET DATE_CORRELATION_OPTIMIZATION OFF 
    GO
    ALTER DATABASE [dbTest] SET TRUSTWORTHY OFF 
    GO
    ALTER DATABASE [dbTest] SET ALLOW_SNAPSHOT_ISOLATION OFF 
    GO
    ALTER DATABASE [dbTest] SET PARAMETERIZATION SIMPLE 
    GO
    ALTER DATABASE [dbTest] SET  READ_WRITE 
    GO
    ALTER DATABASE [dbTest] SET RECOVERY FULL 
    GO
    ALTER DATABASE [dbTest] SET  MULTI_USER 
    GO
    ALTER DATABASE [dbTest] SET PAGE_VERIFY CHECKSUM  
    GO
    ALTER DATABASE [dbTest] SET DB_CHAINING OFF
    

    eine Anschließende Datenrücksicherung ( Wiederherstellung ) und

    ALTER DATABASE dbTest SET ENABLE_BROKER WITH ROLLBACK IMMEDIATE

    führt zum Mißerfolg. ( Bsp funktioniert nicht )

    Erstelle ich die Datenbank mit obigen Script und Importiere die Daten
    ( Managemntstudio: Datenbank -> Task -> Import )

    werde ich erfolgreich über Tabellenänderungen benachrichtigt.

    Demzufolge wirkt entweder
    ALTER DATABASE dbTest SET ENABLE_BROKER WITH ROLLBACK IMMEDIATE
    anders als
    ALTER DATABASE dbTest SET ENABLE_BROKER

    oder es sind noch weitere Einstellungen verantwortlich.

    ALTER DATABASE dbTest SET ENABLE_BROKER auf eine bestehende Datenbank
    funktioniert jedenfalls irgendwie nicht ( Ausführung "unendlich" )

    Edit : 2013-04-29
    Leider bin ich selbst mit dieser Anleitung noch kein Schritt weiter.
    http://dimarzionist.wordpress.com/2009/04/01/how-to-make-sql-server-notifications-work/

    Lösung:

    ohne die Internas genau zu kennen, ist es wohl so, dass [dbo] einem
    bestimmten Benutzer ( Windows Auth. oder SQL-Server Benutzer ) zugeordnet wird.

    Für die Benachrichtigung mittels SqlDependency sind seitens des SQL-Server
    wohl bestimmte Berechtigungen notwendig. Diese werden über den Benutzer ermittelt.
    Der Benutzer scheint über einen internen Key ( UID oä. ) und nicht
    mit Benutzer, Passwort identifiziert zu werden.

    Wird eine neue Datenbank erstellt, existiert der Key zu einem auf dem Server
    existierenden Benutzer. Das Beispiel funktioniert daher.

    Wird eine neue Datenbank angelegt und mit einer Rücksicherung befüllt, wird
    der Benutzer-Key der neuen Datenbank mit dem Key aus der Sicherung überschrieben.
    Dieser Key existiert womöglich aber nicht für den Server, wenn die Datensicherung
    von einem anderen Server stammt !

    Infolge funktioniert das Beispiel nicht mehr. So weit mein Verständnis.

    Mittels nachfolgendem Script wird der Benutzer-Key der gefüllten Datenbank
    auf einen im Server existierenden Benutzer gesetzt.

    USE [master]
    GO
    ALTER AUTHORIZATION ON DATABASE::[dbname] TO [dbuser];
    GO
    

    Infolge funktioniert die Benachrichtigung wieder.


Anmelden zum Antworten