使用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#示例代码如下:

        private const string SQL_CONNECTIONSETTINGS = "";

        static void Main(string[] args)
        {
            //传入连接字符串,启动基于数据库的监听
            SqlDependency.Start(SQL_CONNECTIONSETTINGS);
            HandleMessage();

            Console.Read();
        }

        /// <summary>
        /// 触发处理消息机制
        /// </summary>
        private static void HandleMessage()
        {
            using (SqlConnection connection = new SqlConnection(SQL_CONNECTIONSETTINGS))
            {
                //依赖是基于某一张表的,而且查询语句只能是简单查询语句,不能带top或*,同时必须指定所有者,即类似[dbo].[]
                using (SqlCommand command = new SqlCommand("SELECT [MessageID],[Messages],[CreateTime] FROM [dbo].[Messages]", connection))
                {
                    int messageID = 0;
                    command.CommandType = CommandType.Text;
                    connection.Open();
                    command.Notification = null;
                    SqlDependency dependency = new SqlDependency(command);
                    dependency.OnChange += new OnChangeEventHandler(Dependency_OnChange);

                    SqlDataReader sdr = command.ExecuteReader();
                    while (sdr.Read())
                    {
                        int.TryParse(sdr["MessageID"].ToString(), out messageID);
                        ProcessMessage(messageID);
                        Console.WriteLine("MessageID:{0}\tMessages:{1}\tCreateTime:\t{2}", sdr["MessageID"].ToString(), sdr["Messages"].ToString(), sdr["CreateTime"].ToString());
                        CompleteProcessMessage(messageID, 2);
                    }
                    sdr.Close();
                }
            }
        }

        /// <summary>
        /// SQL消息触发事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private static void Dependency_OnChange(object sender, SqlNotificationEventArgs e)
        {
            SqlDependency dependency = sender as SqlDependency;
            dependency.OnChange -= Dependency_OnChange;
            HandleMessage();
        }

        /// <summary>
        /// 处理消息
        /// </summary>
        /// <param name="messageID">消息编号</param>
        private static void ProcessMessage(int messageID)
        {
            using (SqlConnection connection = new SqlConnection(SQL_CONNECTIONSETTINGS))
            {
                string sql = string.Format(@"INSERT INTO [dbo].[MessagesComplete]
                               SELECT [MessageID],[Messages],1,[CreateTime],GETDATE()
                               FROM [dbo].[Messages] WHERE [MessageID] = {0}
                               DELETE FROM [dbo].[Messages] WHERE [MessageID] = {0}", messageID);
                using (SqlCommand command = new SqlCommand(sql, connection))
                {
                    command.CommandType = CommandType.Text;
                    connection.Open();
                    command.ExecuteNonQuery();
                    command.Dispose();
                }
            }
        }
        /// <summary>
        /// 消息处理完成,更新消息处理状态
        /// </summary>
        /// <param name="messageID">消息编号</param>
        /// <param name="status">状态:1.处理中,2.处理完成,-1.处理失败</param>
        private static void CompleteProcessMessage(int messageID, int status)
        {
            using (SqlConnection connection = new SqlConnection(SQL_CONNECTIONSETTINGS))
            {
                string sql = string.Format("UPDATE [dbo].[MessagesComplete] SET [Status] = {1} WHERE [MessageID] = {0}", messageID, status);
                using (SqlCommand command = new SqlCommand(sql, connection))
                {
                    command.CommandType = CommandType.Text;
                    connection.Open();
                    command.ExecuteNonQuery();
                    command.Dispose();
                }
            }
        }


       

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值