ToD*_*Now 64 c# sql-server monitoring
我有多个应用程序访问同一个数据库,如果其中一个应用程序在某个表中更改了任何内容(更新,插入),我需要收到通知.
数据库和应用程序不在同一台服务器中.
Jar*_*dek 53
你可以使用SqlDependency Class.其预期用途主要用于ASP.NET页面(客户端通知数量较少).
ALTER DATABASE UrDb SET ENABLE_BROKER
Run Code Online (Sandbox Code Playgroud)
实施OnChange事件以获得通知:
void OnChange(object sender, SqlNotificationEventArgs e)
Run Code Online (Sandbox Code Playgroud)
在代码中:
SqlCommand cmd = ...
cmd.Notification = null;
SqlDependency dependency = new SqlDependency(cmd);
dependency.OnChange += OnChange;
Run Code Online (Sandbox Code Playgroud)
它使用Service Broker(基于消息的通信平台)从数据库引擎接收消息.
tom*_*ern 35
为了完整性,我认为还有一些其他解决方案比依赖于SqlDependency(和SqlTableDependency)类的解决方案更正统和更完善.SqlDependency是为Web服务器缓存刷新而设计的,因此实际上并没有提供您在事件生成器中需要的负载弹性.
这里还没有提到其他四个选项:
更改跟踪
资料来源:https://docs.microsoft.com/en-us/sql/relational-databases/track-changes/about-change-tracking-sql-server
更改跟踪是SQL Server中的轻量级通知机制.基本上,随着对任何数据的每次更改,数据库范围的版本号都会递增.然后使用位掩码将版本号写入更改跟踪表,该位掩码包括已更改的列的名称.请注意,实际更改不会持久存在.通知仅包含特定数据实体已更改的信息.此外,由于更改表版本控制是累积的,因此不会保留单个项目的更改通知,并且会被较新的通知覆盖.这意味着如果实体更改两次,更改跟踪将只知道最近的更改.
为了捕获c#中的这些更改,必须使用轮询.可以轮询更改跟踪表,并检查每个更改以查看是否感兴趣.如果感兴趣,则必须直接转到数据以检索当前状态.
更改数据捕获
来源:https://technet.microsoft.com/en-us/library/bb522489(v = sql.105).aspx
变更数据捕获(CDC)比变更跟踪更强大但成本更高.更改数据捕获将基于监视数据库日志来跟踪和通知更改.因此,CDC可以访问已更改的实际数据,并记录所有个别更改.
与更改跟踪类似,为了在c#中捕获这些更改,必须使用轮询.但是,在CDC的情况下,轮询的信息将包含更改详细信息,因此不一定要回到数据本身.
触发队列
资料来源:https://code.msdn.microsoft.com/Service-Broker-Message-e81c4316
此技术取决于需要通知的表上的触发器.每次更改都将触发一个触发器,触发器会将此信息写入服务代理队列.然后可以使用Service Broker消息处理器(上面链接中的示例)通过C#连接队列.
与更改跟踪或CDC不同,队列触发器不依赖于轮询,从而提供实时事件.
CLR
这是我见过的一种技术,但我不推荐它.依赖于CLR进行外部通信的任何解决方案都是充其量的黑客攻击.CLR旨在通过利用C#使编写复杂的数据处理代码变得更容易.它不是设计用于连接外部依赖项,如消息库.此外,CLR绑定操作可能以不可预测的方式在集群环境中中断.
这就是说,设置起来相当简单,因为您需要做的就是使用CLR注册消息传递程序集,然后您可以使用触发器或SQL作业进行调用.
综上所述...
微软一直坚决拒绝解决这个问题空间,这一直令我感到惊讶.从数据库到代码的事件应该是数据库产品的内置功能.考虑到Oracle Advanced Queuing结合ODP.net MessageAvailable事件为10多年前的 C#提供了可靠的数据库事件,这对MS来说是可悲的.
这样做的结果是,这个问题所列出的解决方案都不是很好.它们都具有技术缺陷并且具有显着的设置成本.微软,如果你正在倾听,请理清这个令人遗憾的事态.
使用SqlTableDependency.当记录发生变化时,它是ac#组件引发事件.您可以在以下位置找到其他详情网址 https //github.com/christiandelbianco/monitor-table-change-with-sqltabledependency
它与.NET SqlDependency类似,不同之处在于SqlTableDependency引发包含已修改/已删除或已更新的数据库表值的事件:
string conString = "data source=.;initial catalog=myDB;integrated security=True";
using(var tableDependency = new SqlTableDependency<Customers>(conString))
{
tableDependency.OnChanged += TableDependency_Changed;
tableDependency.Start();
Console.WriteLine("Waiting for receiving notifications...");
Console.WriteLine("Press a key to stop");
Console.ReadKey();
}
...
...
void TableDependency_Changed(object sender, RecordChangedEventArgs<Customers> e)
{
if (e.ChangeType != ChangeType.None)
{
var changedEntity = e.Entity;
Console.WriteLine("DML operation: " + e.ChangeType);
Console.WriteLine("ID: " + changedEntity.Id);
Console.WriteLine("Name: " + changedEntity.Name);
Console.WriteLine("Surname: " + changedEntity.Surname);
}
}
Run Code Online (Sandbox Code Playgroud)
使用SqlDependency类要小心-它存在内存泄漏问题。
只需使用跨平台,.NET 3.5,.NET Core兼容和开源解决方案-SqlDependencyEx。您可以获取通知以及已更改的数据(可以通过通知事件对象中的属性进行访问)。您也可以单独或一起添加DELETE \ UPDATE \ INSERT操作。
这是一个使用SqlDependencyEx多么容易的示例:
int changesReceived = 0;
using (SqlDependencyEx sqlDependency = new SqlDependencyEx(
TEST_CONNECTION_STRING, TEST_DATABASE_NAME, TEST_TABLE_NAME))
{
sqlDependency.TableChanged += (o, e) => changesReceived++;
sqlDependency.Start();
// Make table changes.
MakeTableInsertDeleteChanges(changesCount);
// Wait a little bit to receive all changes.
Thread.Sleep(1000);
}
Assert.AreEqual(changesCount, changesReceived);
Run Code Online (Sandbox Code Playgroud)
请点击链接了解详细信息。该组件已在许多企业级应用程序中进行了测试,并被证明是可靠的。希望这可以帮助。
SqlDependency不会监视它监视您指定的SqlCommand的数据库,所以如果您试图让值插入1个项目中的数据库并在另一个项目中捕获该事件它将无法工作,因为该事件来自SqlCommand 1º项目不是数据库,因为在创建SqlDependency时,您将其链接到SqlCommand,并且只有在使用该项目的命令时才会创建Change事件.
从 SQL Server 2005 开始,您可以选择使用Query Notifications,ADO.NET 可以利用它,请参阅 http://msdn.microsoft.com/en-us/library/t9x04ed2.aspx
| 归档时间: |
|
| 查看次数: |
94008 次 |
| 最近记录: |