[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-eventskonnte 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-2008Lö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 IMMEDIATEerscheint 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_BROKERoder 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.