使用SqlDependency监听MSSQL数据库表变化通知

SqlDependency提供了这样一种机制,当被监测的数据库中的数据发生变化时,SqlDependency会自动触发OnChange事件来通知应用程序,从而达到让系统自动更新数据(或缓存)的目的。

 

首先要对数据库进行配置,配置命令如下:

1.启用Service Broker并查看是否启用成功,is_broker_enabled为1则表明启用成功:

ALTER DATABASE SqlDepTest SET NEW_BROKER WITH ROLLBACK IMMEDIATE;
ALTER DATABASE SqlDepTest SET ENABLE_BROKER;
SELECT is_broker_enabled FROM sys.databases WHERE name = 'SqlDepTest'

2.开启帐号订阅权限,由于sa帐号不支持权限设置,所以需要建立单独的帐号。

use master

GRANT CREATE PROCEDURE TO sqldep
GRANT CREATE QUEUE TO sqldep
GRANT CREATE SERVICE TO sqldep

use master
GRANT SUBSCRIBE QUERY NOTIFICATIONS TO sqldep
exec sp_helprotect NULL, sqldep

 

C#示例代码如下:

 

[csharp] view plain copy
 
    1. private const string SQL_CONNECTIONSETTINGS = "";  
    2.   
    3. static void Main(string[] args)  
    4. {  
    5.     //传入连接字符串,启动基于数据库的监听  
    6.     SqlDependency.Start(SQL_CONNECTIONSETTINGS);  
    7.     HandleMessage();  
    8.   
    9.     Console.Read();  
    10. }  
    11.   
    12. /// <summary>  
    13. /// 触发处理消息机制  
    14. /// </summary>  
    15. private static void HandleMessage()  
    16. {  
    17.     using (SqlConnection connection = new SqlConnection(SQL_CONNECTIONSETTINGS))  
    18.     {  
    19.         //依赖是基于某一张表的,而且查询语句只能是简单查询语句,不能带top或*,同时必须指定所有者,即类似[dbo].[]  
    20.         using (SqlCommand command = new SqlCommand("SELECT [MessageID],[Messages],[CreateTime] FROM [dbo].[Messages]", connection))  
    21.         {  
    22.             int messageID = 0;  
    23.             command.CommandType = CommandType.Text;  
    24.             connection.Open();  
    25.             command.Notification = null;  
    26.             SqlDependency dependency = new SqlDependency(command);  
    27.             dependency.OnChange += new OnChangeEventHandler(Dependency_OnChange);  
    28.   
    29.             SqlDataReader sdr = command.ExecuteReader();  
    30.             while (sdr.Read())  
    31.             {  
    32.                 int.TryParse(sdr["MessageID"].ToString(), out messageID);  
    33.                 ProcessMessage(messageID);  
    34.                 Console.WriteLine("MessageID:{0}\tMessages:{1}\tCreateTime:\t{2}", sdr["MessageID"].ToString(), sdr["Messages"].ToString(), sdr["CreateTime"].ToString());  
    35.                 CompleteProcessMessage(messageID, 2);  
    36.             }  
    37.             sdr.Close();  
    38.         }  
    39.     }  
    40. }  
    41.   
    42. /// <summary>  
    43. /// SQL消息触发事件  
    44. /// </summary>  
    45. /// <param name="sender"></param>  
    46. /// <param name="e"></param>  
    47. private static void Dependency_OnChange(object sender, SqlNotificationEventArgs e)  
    48. {  
    49.     SqlDependency dependency = sender as SqlDependency;  
    50.     dependency.OnChange -= Dependency_OnChange;  
    51.     HandleMessage();  
    52. }  
    53.   
    54. /// <summary>  
    55. /// 处理消息  
    56. /// </summary>  
    57. /// <param name="messageID">消息编号</param>  
    58. private static void ProcessMessage(int messageID)  
    59. {  
    60.     using (SqlConnection connection = new SqlConnection(SQL_CONNECTIONSETTINGS))  
    61.     {  
    62.         string sql = string.Format(@"INSERT INTO [dbo].[MessagesComplete]  
    63.                        SELECT [MessageID],[Messages],1,[CreateTime],GETDATE()  
    64.                        FROM [dbo].[Messages] WHERE [MessageID] = {0}  
    65.                        DELETE FROM [dbo].[Messages] WHERE [MessageID] = {0}", messageID);  
    66.         using (SqlCommand command = new SqlCommand(sql, connection))  
    67.         {  
    68.             command.CommandType = CommandType.Text;  
    69.             connection.Open();  
    70.             command.ExecuteNonQuery();  
    71.             command.Dispose();  
    72.         }  
    73.     }  
    74. }  
    75. /// <summary>  
    76. /// 消息处理完成,更新消息处理状态  
    77. /// </summary>  
    78. /// <param name="messageID">消息编号</param>  
    79. /// <param name="status">状态:1.处理中,2.处理完成,-1.处理失败</param>  
    80. private static void CompleteProcessMessage(int messageID, int status)  
    81. {  
    82.     using (SqlConnection connection = new SqlConnection(SQL_CONNECTIONSETTINGS))  
    83.     {  
    84.         string sql = string.Format("UPDATE [dbo].[MessagesComplete] SET [Status] = {1} WHERE [MessageID] = {0}", messageID, status);  
    85.         using (SqlCommand command = new SqlCommand(sql, connection))  
    86.         {  
    87.             command.CommandType = CommandType.Text;  
    88.             connection.Open();  
    89.             command.ExecuteNonQuery();  
    90.             command.Dispose();  
    91.         }  
    92.     }  
    93. }  
posted @ 2017-07-27 14:08  月月想你,李  阅读(559)  评论(0编辑  收藏  举报