有没有办法通知Web服务器(在我的情况下,在C#中托管MVC2 webapp的Web服务器)数据库发生了变化这一事实?目的是使Web服务器缓存与数据库保持同步。
ASP.NET中有轮询构造允许这样做,但我更喜欢推送系统。我也假设数据库可以由Web服务器本身以外的元素操作。
我对SQL Server / ASP MVC的有限诀窍说,一种方法是创建一个表TRIGGER,它几乎击中了一个会强制更新的URL。
答案 0 :(得分:7)
SqlDependency
是可行的方法。对于高变化率,您最好轮询更改。要了解SqlDependency的工作原理,请阅读The Mysterious Notification。 ASP已经内置了对SqlDependency的支持,即SqlCacheDependency
。如果可能的话,还有LinqToCache将SqlDependency功能添加到任意LINQ查询中。
触发绝对是一个很大的禁忌。你不能让数据库事务在某些URL上等待响应,你的性能将基本没有崩溃。更不用说可用性问题(如果URL没有响应,更新将失败,无论出于何种原因)。
答案 1 :(得分:4)
我自己没有这方面的经验,但是System.Data.SqlClient.SqlDependency
课程看起来就像你需要的那样。
根据MSDN:
SqlDependency非常适合用于ASP.NET的缓存方案 应用程序或中间层服务需要保留某些信息 缓存在记忆中。 SqlDependency允许您接收通知 当数据库中的原始数据发生变化时,缓存即可 被刷新。
答案 2 :(得分:2)
我能想到的唯一方法是编写一个CLR用户定义函数(UDF)并通过感兴趣的表上的insert / update / delete触发器调用它。
UDF应该生成一个信号通知Web服务器并立即返回触发器的线程。出于显而易见的原因,在触发器或正在运行的事务中调用任何可能长时间运行或可能失败的操作(如访问网络)都被认为是非常糟糕的形式。当然,除非您喜欢让生产DBA的愤怒降临你喜欢马克斯韦尔的银锤。
答案 3 :(得分:1)
您的“有限的SQL Server专有技术”已经足够了。你应该创建一个AFTER INSERT,UPDATE,DELETE触发器来完成你需要的操作。
另一件事是,这是一个坏主意,但你可能已经意识到这一点..
解决此类问题的正确方法是使用某种消息队列,例如。 MSMQ。
答案 4 :(得分:0)
要在更改/更新表格内容时从数据库获取通知,您可以使用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);
}
}