发现一个工具 - SqlTableDependency,透过它可以在数据库的数据发生 Insert、Update、Delete 的时候,即时主动发送通知,而且包含异动后的数据都一起随着通知发送出来,我们就来看看它要怎么用?
这个连结里面有介绍 SqlTableDependency 是如何运行的?它利用了原本 SQL Server 就有的功能,来动态地产生通知机制。
开启 Service Broker 功能
SqlTableDependency 相依于 SQL Server 的 Service Broker 功能,将消息透过 Service Broker 广播给订阅者,执行下面的命令就可以开启 Service Broker 功能。
ALTER DATABASE MyDatabase SET ENABLE_BROKER WITH ROLLBACK IMMEDIATE附加 WITH ROLLBACK IMMEDIATE 选项来执行 ALTER DATABASE 命令,会让所有未完成的事务都会回复,而且数据库的任何其他连接都会立即中断,要附加这个选项是因为开启 Service Broker 功能必须要在没有其他使用者在使用的时候,所以请选定良辰吉日再来做这件事。
准备测试数据
我事先在数据库建立了一个数据表 MyDependencyTalbe
,里面有三个字段 Id
、Name
、Description
。

里面预先加入三笔数据

剩下的交给 SqlTableDependency
我们必须要建立一个与数据表相对应的类,但是这个类的名称及里面的属性名称不一定要跟数据表的名称及字段名称相对应,没有相对应的部分我们可以透过附加 Data Annotations 或是建立 ModelToTableMapper
但是如果我们的类名称及属性名称是跟数据表的名称及字段名称相对应的话,就不用做这些事啰。
接着我们就建立一个 SqlTableDependency 的 instance,指定 OnChanged 的事件,调用 Start() 方法,就大功告成了。
SqlTableDependency myDependencyTableDependency; myDependencyTableDependency = new SqlTableDependency(ConnectionString); myDependencyTableDependency.OnChanged += (o, args) => this.OutputNotification(args.ChangeType, args.Entity); myDependencyTableDependency.Start();
执行结果

没有银子弹
在实测的过程中,发现有两件事情要跟大家分享:
- 之前有介绍过在 C# 用 SqlBulkCopy 批次 Insert 大量数据,SqlBulkCopy 在 SQL Server 是用 bcp Utility(bulk copy program Utility)在写入数据的,根本就没有生成 Insert 的 SQL 语句,这部分 SqlTableDependency 就通知不到。
- 性能大大他有点问题,SqlTableDependency 在少量数据异动的运行上看起来速度还可以接受,但是如果数据量大的话就不能接受了,给大家一个参考的数据,在双核、4GB RAM、Windows Server 2012 R2、SQL Server 2016 SP1 的 VM 上,删除 1000 笔数据要 1 秒多,我再试着删除十万笔数据,3 分钟删不完。
如果我们每次 commit 的数据量不是那么大的时候,SqlTableDependency 的确可以帮我们不少忙,例如:在数据异动后有需要更新 Cache 时…,但是每次 commit 的数据量大的时候,就不太适合,各位朋友如果要使用的话,要多多评估。
参考数据
- Audit, monitor and receive SQL Server table change notifications - Documentation
- Enable SQL Server Broker taking too long time
原文:大专栏 [创意料理] 有一个工具可以让数据库的数据在发生 Insert、Update、Delete 时即时主动通知我们