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