簡介:
SqlDependency提供了這樣一種能力:當被監測的數據庫中的數據發生變化時,SqlDependency會自動觸發OnChange事件來通知應用程序,從而達到讓系統自動更新數據(或緩存)的目的。
應用場景:
當數據庫中的數據發生變化時,需要更新緩存,或者需要更新與之相關的業務數據,又或者是發送郵件或者短信什么的等等情況時,如果數據庫是SQL Server,可以考慮使用SqlDependency監控數據庫中的某個表的數據變化,並出發相應的事件。
應用程序前提條件:
在應用程序啟動時,啟動SqlDependency針對SQLServer連接的監控。
在應用程序結束時,停止SqlDependency針對SQLServer連接的監控。
Web應用程序:
protectedvoid Application_Start()
{
System.Data.SqlClient.SqlDependency.Start(ConfigurationManager.ConnectionStrings["Framework_SqlServer"].ConnectionString);
}
protectedvoid Application_End(object sender, EventArgs e)
{
System.Data.SqlClient.SqlDependency.Stop(ConfigurationManager.ConnectionStrings["Framework_SqlServer"].ConnectionString);
}
WINDOWS應用程序:
staticvoid Main(string[] args)
{
_connStr = ConfigurationManager.ConnectionStrings["Framework_SqlServer"].ToString();
SqlDependency.Start(_connStr);//傳入連接字符串,啟動基於數據庫的監聽
…
SqlDependency.Stop(_connStr);//傳入連接字符串,啟動基於數據庫的監聽
}
具體應用:
//當表中的數據發生變化時,出發OnChangeEventHandler事件
privatestaticvoid UpdateGrid()
{
using (SqlConnection connection = newSqlConnection(_connStr))
{
//依賴是基於某一張表的,而且查詢語句只能是簡單查詢語句,不能帶top或*,同時必須指定所有者,即類似[dbo].[]
using (SqlCommand command = newSqlCommand(" SELECT ID,TaskName,CompletionNumber,UploadFilePath,QueryCount,StartTime,EndTime,TaskStatus,DownLoadFilePath,Creater,CreateDate FROM [dbo].[Res_BatchQuery] WHERE ID = 70 ", connection))
{
command.CommandType = CommandType.Text;
connection.Open();
SqlDependency dependency = newSqlDependency(command);
dependency.OnChange += newOnChangeEventHandler(dependency_OnChange);
SqlDataReader sdr = command.ExecuteReader();
Console.WriteLine();
while (sdr.Read())
{
Console.WriteLine("Id:{0}\\TaskName:{1}\\CompletionNumber:{2}", sdr["ID"].ToString(), sdr["TaskName"].ToString(), sdr["CompletionNumber"].ToString());
}
sdr.Close();
}
}
}
//具體事件
privatestaticvoid dependency_OnChange(object sender, SqlNotificationEventArgs e)
{
if (e.Type == SqlNotificationType.Change) //只有數據發生變化時,才重新獲取並數據
{
UpdateGrid();
}
}
需要注意的事項:
1、應用程序開始或者結束時,必須相應的開始或者停止對SQL Server的監控。
2、只有SQL語句中需要查詢的字段才會被監控,沒有查詢的數據發生變化時,並不會觸發dependency_OnChange事件。
3、查詢語句只能是簡單查詢語句,不能帶top或*,同時必須指定所有者,即類似[dbo].[]。
4、WHERE條件中的數據不能太復雜,不然可能不會被監控到。
5、待查詢的字段的數據也不能太復雜。測試時,有個字段保存Json格式的數據。如果將這個字段也寫入到SQL語句中,則不會被監控到。
SQLServer需要的相關配置:
//設置某個數據庫代理的回滾
ALTER DATABASE [DBName] SET NEW_BROKER WITH ROLLBACK IMMEDIATE;
//設置某個數據庫的代理
ALTER DATABASE [DBName] SET ENABLE_BROKER;
//查詢某個數據庫是否已經啟動了代理
SELECT is_broker_enabled FROM sys.databases WHERE name = '[DBName]'
is_broker_enabled 為0表示未啟動代理
is_broker_enabled 為1表示已啟動代理