【问题标题】:How to track changes in many SQL Server databases from .NET application?如何从 .NET 应用程序跟踪许多 SQL Server 数据库中的更改?
【发布时间】:2010-04-22 08:19:28
【问题描述】:

问题:

有很多不同的数据库,由许多不同的应用程序直接填充(没有任何通用的应用程序层)。数据只能通过 SP 访问(根据策略)

任务:

应用程序需要跟踪这些数据库中的变化并在最短的时间内做出反应。

可能的解决方案:

1) 为每个数据库中的每个表创建触发器,这将用事件填充一个表。应用程序将通过 SqlDependency 监视此表。

2) 通过SqlDependency 监视每个数据库中的每个表。

3) 为每个数据库中的每个表创建触发器,这将通知使用托管扩展的应用程序。

最好的方法是什么?

【问题讨论】:

    标签: .net sql-server stored-procedures ado.net sqldependency


    【解决方案1】:

    这可能是一个广泛的话题。首先:使用的SQL Server版本是什么?

    如果您使用的是 SQL 2008,更改数据捕获是首选工具 这一新功能使您能够监控 SQL 2008 中对数据库所做的每一次更改。这包括 DDL 更改以及数据更改。 查看简介here

    如果您使用的是旧版本的 SQL 2008 并且您被允许修改数据库的 DDL,则 选项 3 将是选择之一(在一旦你描述)。不过我不推荐它,因为还有其他事情需要考虑,例如当事务回滚批量插入时停用触发器时会发生什么?? p>

    让您的解决方案在所有这些情况下都能正常工作将是一项艰巨的挑战。

    另一种方法是查看事务日志文件。这种方式是迄今为止最好的,但也是最复杂的方式,因为几乎没有关于专有日志格式的文档。它还绑定到特定版本的 SQL Server。这将导致对所选数据库的无影响监控。

    另一种方法是创建要监控的数据副本,并定期检查是否存在差异。 这样做的好处是无需更改源数据库。以及摆脱事务或批量插入问题。由于最迟在下一次监控运行时,您将能够发现更改。

    性能影响很小,因为它只需要对要监视的表进行主索引连续读取。这是迄今为止与数据库交互的最优化方式。 然而,这种方法将需要相当多的开发工作。我必须知道,因为这是我自去年以来的主要关注点。检查here ;)

    (我希望链接没问题,在这种情况下,因为它的主题,否则我删除它)

    【讨论】:

    • 非常感谢!我从未听说过 SQL 2008 的 CDC 功能,看来这正是我所需要的。
    • 它非常强大,因为很多系统不允许更改 DDL(例如,如果您直接在数据库级别更改 DDL,例如添加触发器,所有 Microsoft Dynamics 系统都会崩溃)。 CDC 对使用数据库的系统完全透明,这就是它如此出色的原因。事实上,因为它为您提供了 DBMS 也可用的所有信息,您将能够创建自定义 TransactionLog。同时,性能影响很小,因为没有特别创建任何内容,但(以前的)内部信息被适当地公开了。
    【解决方案2】:

    您不查看使用 SQL 分析器的可能性吗?使用过滤器可以只选择更新操作,然后写入日志。

    【讨论】:

    • 它如何影响性能?如何从更新语句中获取参数?通过查询解析?或者还有其他方法?
    • Profiler 可以在网络中的任何计算机上启动,因此这减少了处理器使用的陷阱。参数也包含在日志中
    【解决方案3】:

    您可以使用 SqlDependency 类的开源实现 - SqlDependencyEx。它使用数据库触发器和本机 Service Broker 通知来接收有关表更改的事件。这是一个用法示例:

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

    使用 SqlDependecyEx,您可以只监控 INSERT 或 DELETE,避免 UPDATE。希望这会有所帮助。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-01-31
      • 2021-05-16
      • 2017-09-05
      相关资源
      最近更新 更多