12.6SQLServer2005所提供的主动通知
来源:优易学  2010-1-12 11:42:20   【优易学:中国教育考试门户网】   资料下载   IT书店

 

在范例中通过限制查询产品的编号范围来避免 SQL Server 关注太多的数据,从而避免造成频繁通知多个前端应用程序。你可以通过范例程序的主菜单重复打开两个如图12-10 所示的程序界面,以此模拟不同人同时访问数据,但彼此设置不同产品编号范围的查询,而其中有部分范围重迭。然后分别调用不同的记录来修改,测试是否当重迭的记录被其中一个窗口改变后,两个窗口都会接到来自 SQL Server 的通知。反之,若更新的是某个窗口自己特有的数据范围,则只有该窗口会接到通知。范例程序代码主要的部分如程序代码列表12-9所示:

程序代码列表12- 9 通过 SqlDependency 对象设置 SqlCommand 对象的 Notification 属性,以注册通知的相关设置

Dim conn As New SqlConnection( _

ConfigurationSettings.ConnectionStrings("AWConnectionString").ConnectionString)

Delegate Sub PopulateList()

Private Sub notificationForm_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) _

Handles MyBase.Load

SqlDependency.Start(ADONET20.My.Settings.AdventureWorksConnection)

'取得初始的数据

ListProducts()

End Sub

Sub OnDependencyChanged(ByVal sender As Object, ByVal e As SqlNotificationEventArgs)

'SqlDependency 对象的 OnChanged 事件触发时

'要执行的商业逻辑

Dim dR As DialogResult

dR = MessageBox.Show("数据已经修改了. 要更新数据吗?", e.Info.ToString, _

MessageBoxButtons.YesNo, MessageBoxIcon.Question)

If dR = Windows.Forms.DialogResult.Yes Then

'交给 Form 的主线程更新数据

Me.Invoke(New PopulateList(AddressOf ListProducts))

End If

End Sub

Public Sub ListProducts()

'重新装载数据

'SqlDependency 设置后,仅会注册一次的事件通知

Dim dep As New SqlDependency()

'设置 SqlDependency 对象的 OnChanged 事件发生时,要调用哪个 event handler

AddHandler dep.OnChanged, AddressOf OnDependencyChanged

'限制查询的范围,避免太大的范围导致多人都影响到这个范围内的数据,而让 SQL Server

'频频触发通知

Using cmd As New SqlCommand( _

"SELECT ProductID, Name, ListPrice FROM Production.Product " & _

"WHERE ProductID BETWEEN @Start AND @End", conn)

With cmd

.Parameters.Add(New SqlParameter("@Start", Data.SqlDbType.Int))

.Parameters.Add(New SqlParameter("@End", Data.SqlDbType.Int))

.Parameters(0).Value = txtStart.Text

.Parameters(1).Value = txtEnd.Text

End With

'自动帮我们设置 SqlCommand 的 Notification 属性所需的 SqlNotificationRequest 对象

'可以通过 Debug 来观察 SqlCommand 对象执行前后的关系

dep.AddCommandDependency(cmd)

productListBox.Items.Clear()

conn.Open()

Dim reader As SqlDataReader = cmd.ExecuteReader()

While reader.Read()

productListBox.Items.Add(reader("ProductID") & " - " & _

reader("Name").ToString & ": " & reader("ListPrice").ToString)

End While

End Using

conn.Close()

End Sub

在上述范例程序代码中,首先是在 Global.asax 文件内的 Application_Start 事件加上通过 SqlDependency 类的静态方法 Start 启动接听,Start 方法需要传递数据库连接字符串。它会完成如下的操作:

打开一条新的不经过 connection pool 的连接到 SQL Server 2005,由于 SQL Server 2000 之前的版本并不支持这些机制,所以通过 SqlDependency 类连接到 SQL Server 2000 之前的版本不会有作用。

在服务器上创建一个新的队列,并赋予唯一名称。

在该队列上创建一个唯一名称的服务。

在服务器上创建一个新的存储过程,在客户端不再听队列时,清除掉上述临时建置的各种对象。

侦听队列所收到的更改通知。

需要强调的是不管调用 Start 方法几次,每个程序(Process)只会开一条连接到 SQL Server 去听数据的变化。也由于是正常打开连接到 SQL Server,所以若客户端应用程序和服务器端之间有防火墙,也不会影响这个通知机制。否则,若防火墙阻止对 SQL Server 创建连接,则原本就访问不到 SQL Server 的数据,也就不必谈还需要在数据变化后通知了。但也由于需要创建额外的连接到 SQL Server,所以这种机制比较适用于应用程序服务器(如 IIS、COM+)通过缓存访问 SQL Server 的架构,而不是有个几百台前端应用程序同时访问 SQL Server 的 client/server 架构,否则固定几百条连接连在 SQL Server 上,将会因为过多连接而拖垮 SQL Server。

可在范例程序中通过SqlCommand 实例中的T-SQL 更改记录,但并没有自动更新 ListBox 内各条记录的数据,而是在收到 SQL Server 记录改变的通知后,通过事件触发指到OnDependencyChanged 函数调用主线程重新执行 ListProducts 方法,从相关数据表读出更新后的记录来重设 ListBox 的内容。当然,你也可以利用另外的应用程序来更新 Prodution.Product 数据表,如 SQL Server Management Studio,就能看到如图12-10 被通知的画面。

上一页  [1] [2] [3] [4] 下一页

责任编辑:cyth

文章搜索:
 相关文章
热点资讯
热门课程培训