我在VB.net 2010
和SQL 2008
上开发此应用程序
我希望客户端收到数据库更新的通知,而应用程序则使用计时器在指定的一分钟内检查数据库是否发生了更改,这真的很低效。我读过关于query notification
、sqldependency
、service broker
的文章,但后来我读到一些文章说,如果我有100个客户端,并且我正在使用查询通知将通知推送到我的应用程序,它们可能不会有效
有人会帮助我做什么,以及我如何做(如果有例子的话,那真的很有帮助)。提前感谢!
查询通知将推送到Service Broker服务,而不是直接推送到您的应用程序。请参阅神秘通知了解其工作原理。您的应用程序正在等待通知,方法是在数据库上发布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只能通知您数据已更改,但不会推送新的数据。一旦收到通知,应用程序必须通过再次运行查询来刷新其本地数据集。
小心使用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);
使用SqlDependencyEx,您可以只监视UPDATE,避免DELETE和INSERT。希望这能有所帮助。
如果您不手动更新数据库,并且所有数据操作都在您的应用程序中,那么您应该在应用程序服务层或业务层而不是数据库中检测更改,以防您依赖数据库技术,并且很难访问其他数据库。另一方面,如果您对数据库有手动更新,或者对数据库的依赖性不重要,您可以使用CDC(chane数据捕获)将更改推送到service broker,然后您的应用程序从service broker弹出更改,然后通过与SignalR相同的双向http通信技术将其发送到客户端。