老技術記錄-C#+SqlServer使用SqlDependency監聽數據庫表變化


開發環境: .net / C# (.net core理論上也可以)

數據庫:MS SQL Server 2005 以上 (我用的sqlserver2012)

功能:SqlDependency提供了一種機制,當被監聽的數據庫中的數據發生變化時,SqlDependency會自動觸發OnChange事件來通知應用程序,從而達到讓應用程序實時更新數據(或緩存)的目的,而不用定期請求后端,如果加上SignalR技術,基本可以實現實時通信。

我的場景:每天數據變化少,一天不超過十次,但是每次都希望得到提醒,並反應到前台web頁面上。

實現步驟:

1、數據庫啟用 Service Broker

檢查數據庫是否啟用了Service Broker

SELECT is_broker_enabled FROM sys.databases WHERE name = '數據庫名' 

查詢結果:is_broker_enabled de 結果是  0,代表數據庫沒有啟動 Service Broker

解決辦法:

use 數據庫名
go

ALTER DATABASE 數據庫名 SET NEW_BROKER WITH ROLLBACK IMMEDIATE; 

ALTER DATABASE 數據庫名 SET ENABLE_BROKER; 

注:兩句同時執行,單獨執行會顯示 "正在回滾不合法事務。估計回滾已完成: 100%"

再次查詢is_broker_enabled狀態,狀態為1,數據庫沒有啟動 Service Broker成功。

2、Webconfig 中啟用緩存

在<system.web>節點加入

    <caching>
      <sqlCacheDependency enabled="true" pollTime="1000">

        <databases>
          <add name="PDMCAPPS" connectionStringName="數據庫連接字符串" pollTime="1000"/>
        </databases>
      </sqlCacheDependency>

    </caching>

3、在Global.asax添加啟用和停止監聽

    string connectionString = 
    ConfigurationManager.ConnectionStrings["數據庫連接字符串名稱"].ConnectionString;

    void Application_Start(object sender, EventArgs e) 
    {
        // Code that runs on application startup
        System.Data.SqlClient.SqlDependency.Start(connectionString);


    }
    
    void Application_End(object sender, EventArgs e) 
    {
        //  Code that runs on application shutdown
        System.Data.SqlClient.SqlDependency.Stop(connectionString);


    }

4、主程序代碼

    private static string conn = ConfigurationManager.ConnectionStrings["連接字符串名稱"].ConnectionString;
    static SqlDependency dependency;
    protected void Page_Load(object sender, EventArgs e)
    {
        SqlDependency.Start(conn); //傳入連接字符串,啟動基於數據庫的監聽
        if (!IsPostBack)
        {
            Update(conn);
        }
    }

    //使用SqlDependency監控數據庫表變化
    private void Update(string conn)
    {
        using (SqlConnection connection = new SqlConnection(conn))
        {
            StringBuilder strsql = new StringBuilder();
            //對被監控的目標表做簡單查詢,此處 要注意 不能使用* 表名要加[dbo] 否則會出現一直調用執行 OnChange
            strsql.Append(@"sql查詢語句,查詢目標表");            
            using (SqlCommand command = new SqlCommand(strsql.ToString(), connection))
            {
                connection.Open();
                command.CommandType = CommandType.Text;
                dependency = new SqlDependency(command);
                dependency.OnChange += new OnChangeEventHandler(dependency_OnChange);//添加監控,檢測數據表變化
                //必須要執行一下command
                command.ExecuteNonQuery();
                //Console.WriteLine(dependency.HasChanges);
                //connection.Close();
            }
        }
        
    }

    //檢測到數據表變化后執行動作
    private void dependency_OnChange(object sender, SqlNotificationEventArgs e)
    {
        if (e.Type == SqlNotificationType.Change)
        {
            //這里要再次調用
            Update(conn);

            //刷新前台頁面
            Response.AddHeader("Refresh", "0");
        }

    }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM