Sqlserver
 sql >> Datenbank >  >> RDS >> Sqlserver

Wie bereinige ich SqlDependency aus dem SQL Server-Speicher?

Es gibt ein bestimmtes Verhalten der Microsoft SqlDependency-Klasse. Auch wenn Sie die SqlDependency.Stop()-Methode aufrufen, lassen Sie SqlCommand und SqlConnection los – Konversationsgruppen (sys.conversation_groups) und Konversationsendpunkte (sys.conversation_endpoints) bleiben weiterhin in der Datenbank. Es sieht so aus, als ob SQL Server jeden Konversationsendpunkt lädt und den gesamten zulässigen Speicher verwendet. Hier Tests, die es beweisen. Um also alle ungenutzten Konversationsendpunkte zu bereinigen und den belegten Speicher freizugeben, müssen Sie diesen SQL-Code für Ihre Datenbank starten:

DECLARE @ConvHandle uniqueidentifier
DECLARE Conv CURSOR FOR
SELECT CEP.conversation_handle FROM sys.conversation_endpoints CEP
WHERE CEP.state = 'DI' or CEP.state = 'CD'
OPEN Conv;
FETCH NEXT FROM Conv INTO @ConvHandle;
WHILE (@@FETCH_STATUS = 0) BEGIN
    END CONVERSATION @ConvHandle WITH CLEANUP;
    FETCH NEXT FROM Conv INTO @ConvHandle;
END
CLOSE Conv;
DEALLOCATE Conv;

Außerdem gibt SqlDependency Ihnen nicht die Möglichkeit, ALLE Änderungen der Tabelle zu erhalten. Daher erhalten Sie während der erneuten Subskription von SqlDependency keine Benachrichtigung über Änderungen.

Um all diese Probleme zu vermeiden, habe ich eine andere Open-Source-Realisierung der SqlDependency-Klasse verwendet – SqlDependencyEx . Es verwendet Datenbankauslöser und native Service Broker-Benachrichtigungen, um Ereignisse über Änderungen der Tabelle zu erhalten. Dies ist ein Anwendungsbeispiel:

int changesReceived = 0;
using (SqlDependencyEx sqlDependency = new SqlDependencyEx(
          TEST_CONNECTION_STRING, TEST_DATABASE_NAME, TEST_TABLE_NAME)) 
{
    sqlDependency.TableChanged += (o, e) => changesReceived++;
    sqlDependency.Start();

    // Make table changes.
    MakeTableInsertDeleteChanges(changesCount);

    // Wait a little bit to receive all changes.
    Thread.Sleep(1000);
}

Assert.AreEqual(changesCount, changesReceived);

Hoffe das hilft.