SQL Server通知web服务器表的变化

本文关键字:变化 服务器 web Server 通知 SQL | 更新日期: 2023-09-27 18:10:32

是否有一种方法可以通知web服务器(在我的情况下,在c#中托管MVC2 web应用程序的web服务器)数据库发生变化的事实?目的是保持web服务器缓存与数据库同步。

在ASP中有轮询结构。NET允许这样做,但我更喜欢推送系统。我还假设数据库可以被web服务器本身以外的元素操纵。

我有限的SQL Server/ASP MVC知识说,一种方法是通过创建一个表触发器,几乎击中一个url,这将强制更新。

SQL Server通知web服务器表的变化

如果变化率适中,SqlDependency是可行的方法。对于高变化率,你最好进行民意调查。要了解SqlDependency是如何工作的,请阅读神秘通知。ASP已经内置了对SqlDependency的支持,即SqlCacheDependency。如果可能的话,LinqToCache还可以为任意LINQ查询添加SqlDependency功能。

触发器绝对是一个大禁忌。您不能让数据库事务等待某个URL响应,否则您的性能将崩溃到几乎为零。更不用说可用性问题(如果URL不响应,无论出于何种原因,更新都会失败)。

我自己没有经验,但是System.Data.SqlClient.SqlDependency类看起来像你需要的。

根据MSDN:

SqlDependency是缓存场景的理想选择。网应用程序或中间层服务需要保留某些信息缓存在内存中。SqlDependency允许您接收通知当数据库中的原始数据发生变化时,缓存可以被刷新。

我能想到的唯一方法是编写一个CLR用户定义函数(UDF),并通过感兴趣的表上的插入/更新/删除触发器来调用它。

UDF应该生成一个线程,该线程向web服务器发出信号并立即返回到触发器。由于显而易见的原因,在触发器或正在运行的事务中调用任何可能长时间运行或可能失败的操作(例如访问网络)被认为是非常糟糕的。当然,除非您喜欢让生产dba像麦克斯韦的银锤那样对您大发雷霆。

你的"有限的SQL Server知识"已经足够好了。你应该创建一个AFTER INSERT, UPDATE, DELETE触发器来做你需要做的事情。

另一件事是,这是一个坏主意,但你可能已经意识到…

解决这类问题的正确方法是使用某种消息队列。MsMQ .

要在表内容更改/更新时从数据库获取通知,您可以使用TableDependency

与。net SqlDependency的不同之处在于,TableDependency引发的事件包含数据库表值的更改/删除/插入。

使用SqlDependency,你必须执行一个select来获取新的数据,任何时候SqlDependency通知你的代码在数据库表上有一些变化。

使用TableDependency可以避免这种情况,因为您收到的事件包含所有删除/插入/修改的值:

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);
    }
}