SqlNotificationAuthType也支持集
成的身份验证。您可以显式地指定订阅超时值和SQL Server Service Broker的SERVICE名称。SERVICE名称通常设置为空,如例子中所示,但也可以显式地将内置的SqlQueryNotificationService指定为SERVICE名称。最有可能被改写的参数是SqlNotificationTransport和timeout。注意这些参数只能应用于SqlDependency,因为参数指定的是服务器端分发器的行为。使用SqlNotificationRequest的时候并不会使用分发器。
使用SqlNotificationRequest
使用SqlNotificationRequest只是在配置方面要比SqlDependency复杂一点,但主要取决于您的程序如何处理消息。当您使用SqlDependency时,服务器上的通知被发送到MSDB数据库的SqlQueryNotificationService,并由它替您处理通知。使用SqlNotificationRequest时您必须自己处理消息。这里有一个简单的示例,使用SqlNotificationRequest以及我们在本文前面定义的SERVICE。
using System; using System.Data; using System.Data.Sql; using System.Data.SqlClient; class Class1 { string connstring = null; SqlConnection conn = null; SqlDataReader rdr = null; static void Main(string[] args) { connstring = GetConnectionStringFromConfig(); conn = new SqlConnection(connstring)); Class1 c = new Class1(); c.DoWork(); } void DoWork() { conn.Open(); rdr = GetJobs(2); if (rdr != null) { rdr.Close(); WaitForChanges(); } conn.Dispose(); } public SqlDataReader GetJobs(int JobId) { using (SqlCommand cmd = new SqlCommand( "Select job_id, job_desc from dbo. jobs where job_id = @id", conn)) {
try { cmd.Parameters.AddWithValue("@id", JobId); SqlNotificationRequest not = new SqlNotificationRequest(); not.Id = new Guid(); // this must be a service named MyService in the pubs database // associated with a queue called notificationqueue (see below) // service must go by QueryNotifications contract not.Service = "myservice"; not.Timeout = 0; // hook up the notification request cmd.Notification = not; rdr = cmd.ExecuteReader(); while (rdr.Read()) Console.WriteLine(rdr[0]); rdr.Close(); } catch (Exception ex) { Console.WriteLine(ex.Message); } return rdr; } } public void WaitForChanges() { // wait for notification to appear on the queue // then read it yourself using (SqlCommand cmd = new SqlCommand( "WAITFOR (Receive convert(xml,message_body) from notificationqueue)", conn)) { object o = cmd.ExecuteScalar(); // process the notification message however you like Console.WriteLine(o); } }
|
使用SqlNotificationRequest的强大之处(当然也包括额外的工作)就是由您自己等待和处理查询通知。如果您使用SqlDependency,那么在接收到查询通知之前您甚至无需连接数据库。事实上不需要为了接收SqlNotificationRequest的通知而进行等待;可以每隔一段时间轮询一次消息队列。SqlNotificationRequest另一个用处就是编写一个特别的应用程序,即使通知已经激活了,该应用程序也不会运行。当应用程序启动后,它将连接到消息队列并决定缓存中(由于上次运行应用程序)哪些内容是无效的。
探讨一下这样的应用程序,它们为了等待一条通知需要花费好几个小时或者几天,这种应用程序向我们提出了问题: “如果数据不发生改变,那么通知何时消失呢?” 唯一可以导致通知消失的情况(例如,清理了数据库的订阅表)就是通知被引发或者通知过期。数据库管理员如果为那些始终留在数据库中的订阅(因为它们会使用SQL资源并且增加查询和数据更新的成本)而恼火的话,可以在SQL Server中手动地清理通知。首先查询SQL Server 2005动态视图,找出那些不想要的通知订阅,然后使用下面的命令删除它们:
-- look at all subscriptions SELECT * FROM sys.dm_qn_subscriptions -- pick the ID of the subscription that you want, then -- say its ID = 42 KILL QUERY NOTIFICATION SUBSCRIPTION 42
|