開發環境: .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"); } }
