如何从 .NET 应用程序跟踪许多 SQL Server 数据库中的更改?

发布于 2024-08-29 10:47:11 字数 315 浏览 15 评论 0原文

问题:

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

任务:

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

可能的解决方案:

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

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

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

哪个是最好的方法?

Problem:

There are a lot of different databases, which is populated by many different applications directly (without any common application layer). Data can be accessed only through SP (by policy)

Task:

Application needs to track changes in these databases and react in minimal time.

Possible solutions:

1) Create trigger for each table in each database, which will populate one table with events. Application will watch this table through SqlDependency.

2) Watch each table in each database through SqlDependency.

3) Create trigger for each table in each database, which will notify application using managed extension.

Which is the best way?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

一张白纸 2024-09-05 10:47:11

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

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

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

让您的解决方案在所有这些情况下正常工作将是一个安静的挑战。

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

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

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

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

This can be an extensive topic. First of all: What is the SQL Server version used?

if your are using SQL 2008 the Change Data Capture is the tool of choice
This new feature enables you to monitor EVERY change made to databases within SQL 2008. This includes DDL changes as well as changes to the data.
Check an introduction here.

If you are using an older version of SQL 2008 and you are allowed to modify the DDL of the database the option 3 would be the one of choice (of the once you described). I would not recommend it though, since there are other things to consider, like what happens when a transaction rolls back or when triggers are deactivated when bulk inserting for example?

It will be quiet a challenge to make your solution work properly in all of these cases.

Another way you could go is to watch the Transaction Log file. This way by far the best, but also most complex way of doing it, since there is almost no documentation on the proprietary log format. Also it's bound to a specific version of SQL Server. This will result in a no impact monitoring of the chosen databases.

Yet another approach is creating a copy of the data that is to be monitored and periodically check if there are differences.
This has the benefit that NO changes to the source databases have to be made. As well as get rid of transaction or bulk inserting issues. Since latest at the next monitoring run you will be able to discover the changes.

The performance impact is rather minimal since it would only require a primary index consecutive read for the tables that are to be monitored. And this is by far the most optimized way of interacting with a database.
This approach will however require quite a development effort. I have to know, since this is my prime focus since the last years. Check here ;)

(I hope linking is ok, in this case since its on topic otherwise I remove it)

套路撩心 2024-09-05 10:47:11

您是否不考虑使用 SQL 探查器的可能性。使用过滤器,您可以仅选择更新操作,然后写入日志。

Don't you review possibility to use SQL profiler. Using filter you can select only update operations, then write to log.

翻身的咸鱼 2024-09-05 10:47:11

您可以使用 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。希望这有帮助。

You can use an open source realization of the SqlDependency class - SqlDependencyEx. It uses a database trigger and native Service Broker notification to receive events about the table changes. This is an usage example:

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

With SqlDependecyEx you are able to monitor just INSERT or DELETE, avoiding UPDATE. Hope this helps.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文