VB.net 2010
我在和上开发这个应用程序SQL 2008
。
我希望通知客户端有关数据库的更新,并且应用程序用于使用计时器检查数据库在指定分钟内的更改,这确实效率不高。我阅读了有关query notification
, sqldependency
,的内容service broker
,但后来我读到一些内容,说如果我有 100 个客户端并且我正在使用查询通知将通知推送到我的应用程序,它们可能效率不高。
有人会帮助我应该做什么,以及我该怎么做(如果有示例,那将非常有帮助)。提前致谢!
3 回答
查询通知将推送到 Service Broker 服务,而不是直接推送到您的应用程序。请参阅神秘通知以了解其工作原理。您的应用程序正在通过在数据库上WAITFOR(RECEIVE)
发布语句来等待通知。这意味着 100 个客户端中的每一个都占用一个 SQL Server 工作线程(这是有限的,请参阅选项)。我已经看到这在生产中与 +1000 个客户一起工作(在提高了最大工作线程选项之后),但我建议不要这样做。max worker threads
我的建议是使用 SqlDependency/QueryNotifications 对更改进行一项服务监控。然后,该服务将使用 WCF 将通知推送到所有正在运行的应用程序。您将订阅通用更改 ( the table Foo was changed
),而不是特定更改 ( the row x in table Foo was inserted
)。
作为一般规则,SqlDependency/Query Notifications 只能通知您数据已更改,但不会推送新数据。一旦收到通知,应用程序必须通过再次运行查询来刷新其本地数据集。
小心使用SqlDependency类 - 它存在内存泄漏问题。但是,您可以使用 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,您可以只监控 UPDATE,避免 DELETE 和 INSERT。希望这可以帮助。
如果您不手动更新数据库并且所有数据操作都在您的应用程序中,您应该检测应用程序服务层或业务层而不是db的变化,以防您依赖数据库技术并且很难访问其他数据库。另一方面,如果您手动更新 db 或对 db 的依赖并不重要,您可以使用 CDC(chane 数据捕获)并将更改推送到服务代理,您的应用程序从服务代理弹出更改,然后通过双向 http 通信技术将它们发送到客户端与 SignalR 相同。