【问题标题】:SQL Server notify web server of table changeSQL Server 通知 Web 服务器表更改
【发布时间】:2011-10-03 22:22:35
【问题描述】:

有没有办法通知 Web 服务器(在我的例子中,是在 C# 中托管 MVC2 webapp 的 Web 服务器)数据库发生更改的事实?目的是保持 Web 服务器缓存与数据库同步。

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

我对 SQL Server/ASP MVC 的有限知识说,一种方法是创建一个表 TRIGGER,该表几乎会命中一个将强制更新的 url。

【问题讨论】:

    标签: c# sql-server asp.net-mvc


    【解决方案1】:

    SqlDependency 是要走的路,如果变化率适中的话。对于高变化率,您最好轮询变化。要了解 SqlDependency 的工作原理,请阅读 The Mysterious Notification。 ASP 已经内置了对 SqlDependency 的支持,即SqlCacheDependency。如果可能的话,还有LinqToCache 将 SqlDependency 功能添加到任何任意 LINQ 查询。

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

    【讨论】:

    • 似乎 SqlCacheDependency(SqlCommand) 是我正在寻找的,因为它努力确保交付。但是,轮询比查询通知方法更可取的建议让您迷失了方向。轮询一次的成本是否比检查请求的通知查询是否受到某些插入/更新/删除影响所需的测试更有效?
    • 发送通知的成本很高。如果您仅设置通知以立即因高更改率而失效,则最好直接检查该值。是一条细线,其中更好的轮询点因应用程序而异,因表而异。您必须在重负载下测量并查看一个与另一个的影响。
    【解决方案2】:

    我自己没有这方面的经验,但System.Data.SqlClient.SqlDependency 课程看起来很适合您。

    根据 MSDN:

    SqlDependency 非常适合缓存场景,您的 ASP.NET 应用程序或中间层服务需要保留某些信息 缓存在内存中。 SqlDependency 允许您接收通知 当数据库中的原始数据发生变化时,缓存可以 刷新。

    【讨论】:

      【解决方案3】:

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

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

      【讨论】:

        【解决方案4】:

        您的“SQL Server 知识有限”已经足够了。您应该创建一个 AFTER INSERT, UPDATE, DELETE 触发器来执行您需要的操作。

        另一件事是,这是一个坏主意,但您可能已经意识到这一点..

        解决此类问题的正确方法是使用某种消息队列,例如。 MsMQ。

        【讨论】:

          【解决方案5】:

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

          与 .NET SqlDependency 的区别在于 TableDependency 引发包含更改/删除/插入的数据库表值的事件。

          使用SqlDependency,您必须随时执行选择以获取新数据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);
              }
          }
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2010-10-27
            • 1970-01-01
            • 1970-01-01
            • 2010-12-06
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2017-08-18
            相关资源
            最近更新 更多