복붙노트

[SQL] 어떻게 SQL Server 메모리 깨끗 SqlDependency합니까?

SQL

어떻게 SQL Server 메모리 깨끗 SqlDependency합니까?

어떻게 만료 SqlDependency 개체를 제거하기 위해 SQL 서버를 정리합니까? 나는 SqlDepedency 객체에서 이벤트를받은 후, 나는 새로운 이벤트를 얻을 수 있습니다 전에 새로 만들어야합니다. 그러나 SQL Server 프로세스 등반의 메모리 사용이 허용 된 메모리 (SQL Server Express의) 부족까지. 어떻게 된 쿼리 제거합니까?

암호:

// Func: RegisterTableListener
using (SqlConnection cn = new SqlConnection(Properties.Settings.Default.DatabseEventConnectionString))
{
if (cmd == null)
{
    cmd = cn.CreateCommand();

    cmd.CommandType = CommandType.Text;
    cmd.CommandText = "SELECT HostName, LastStatus, LastDetails, xml FROM dbo.[SystemTable]";
}

lock (cmd)
{
    cmd.Connection = cn;
    cn.Open();
    cmd.Notification = null;

    //  creates a new dependency for the SqlCommand
    if (dep == null)
        dep = new SqlDependency(cmd);
    //  creates an event handler for the notification of data
    //      changes in the database.
    dep.OnChange += new OnChangeEventHandler(dependency_OnChange);


    using (SqlDataReader reader = cmd.ExecuteReader())
    {
    // code here to read
    }
}
}

// Func dependency_OnChange
//SqlDependency dep = sender as SqlDependency;
dep.OnChange -= dependency_OnChange;
RegisterTableListener();

해결법

  1. ==============================

    1.마이크로 소프트 SqlDependency 클래스의 특정 행동이있다. 여전히 데이터베이스에서 대화 그룹 (sys.conversation_groups)와 대화 엔드 포인트 (sys.conversation_endpoints를) 유지 - 당신이 SqlDependency.Stop () 메서드를 호출해도, SqlCommand를하고도록 SqlConnection을 놓습니다. SQL 서버는 모든 대화 끝점을로드하고 허용 된 모든 메모리를 사용하는 것 같습니다. 그것을 증명 테스트 여기. 그래서, 사용하지 않는 모든 대화 끝점을 청소하고 당신이 당신의 데이터베이스에 대해이 SQL 코드를 시작하는 모든 차지하는 메모리를 해제합니다 :

    마이크로 소프트 SqlDependency 클래스의 특정 행동이있다. 여전히 데이터베이스에서 대화 그룹 (sys.conversation_groups)와 대화 엔드 포인트 (sys.conversation_endpoints를) 유지 - 당신이 SqlDependency.Stop () 메서드를 호출해도, SqlCommand를하고도록 SqlConnection을 놓습니다. SQL 서버는 모든 대화 끝점을로드하고 허용 된 모든 메모리를 사용하는 것 같습니다. 그것을 증명 테스트 여기. 그래서, 사용하지 않는 모든 대화 끝점을 청소하고 당신이 당신의 데이터베이스에 대해이 SQL 코드를 시작하는 모든 차지하는 메모리를 해제합니다 :

    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;
    

    또한, SqlDependency는 당신에게 테이블의 모든 변경 사항을받을 수있는 기회를 제공하지 않습니다. 그래서, 당신은 SqlDependency를 다시 구독 기간 동안 변경 사항에 대한 알림을받지 않습니다.

    내가 SqlDependency 클래스의 또 다른 오픈 소스 구현을 사용했던 모든 문제를 방지하려면 - SqlDependencyEx합니다. 이 테이블의 변경 사항에 대한 이벤트를 수신하기 위해 데이터베이스 트리거 및 기본 서비스 브로커 알림을 사용합니다. 이것은 사용 예입니다 :

    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);
    

    도움이 되었기를 바랍니다.

  2. from https://stackoverflow.com/questions/8511806/how-do-i-clean-sqldependency-from-sql-server-memory by cc-by-sa and MIT license