浅析SQL Server 2005中的主动式通知机制
一、引言
在開發(fā)多人同時(shí)訪問的Web應(yīng)用程序(其實(shí)不只這類程序)時(shí),開發(fā)人員往往會(huì)在緩存策略的設(shè)計(jì)上狠下功夫。這是因?yàn)?#xff0c;如果將這種環(huán)境下不常變更的數(shù)據(jù)臨時(shí)存放在應(yīng)用程序服務(wù)器或是用戶機(jī)器上的話,可以避免頻繁地往返訪問數(shù)據(jù)庫—而數(shù)據(jù)庫訪問是要符出昂貴代價(jià)的。以往在低版本的SQL Server(SQL Server 2000及以前版本)中,當(dāng)需要提供數(shù)據(jù)庫內(nèi)他人更新后的狀況時(shí),主要是通過輪詢數(shù)據(jù)庫機(jī)制來提供對(duì)數(shù)據(jù)庫的不斷查詢;也可能是借助于存儲(chǔ)于數(shù)據(jù)庫表格中的觸發(fā)器或者通過消息隊(duì)列方式來達(dá)到通知目的。如今,作為微軟.NET 2.0戰(zhàn)略的重要組成部分之一的SQL Server 2005首次引入了主動(dòng)式通知(Query Notification)機(jī)制。SQL Server 2005在所使用數(shù)據(jù)更改時(shí),會(huì)主動(dòng)地通知你。這種新的設(shè)計(jì)模式會(huì)讓你在系統(tǒng)數(shù)據(jù)未更新時(shí),減輕浪費(fèi)網(wǎng)絡(luò)來回輪詢的負(fù)擔(dān),從而有可能極大地提高系統(tǒng)性能。
本文中,我想通過一個(gè)簡單的Windows桌面表單示例(基于SQL Server 2005的范例數(shù)據(jù)庫AdventureWorks)向讀者展示SQL Server 2005中這種新的主動(dòng)地通知工作機(jī)理。
【另注】由于Visual Studio 2005的革命性變化,你可以極為容易地把這個(gè)例子更改到Web應(yīng)用程序場(chǎng)合下。
二、SQL Server 2005中的主動(dòng)式通知
主動(dòng)式通知(也稱為“查詢通知”),是微軟ADO.NET和SQL Server小組協(xié)作開發(fā)的新成果。它允許你對(duì)數(shù)據(jù)進(jìn)行緩沖并且僅在SQL Server中的數(shù)據(jù)發(fā)生變化時(shí)才發(fā)出通知;一旦接到通知,你就可以刷新相應(yīng)的緩沖區(qū)或者采取其它必要的措施。
在SQL Server 2005中引入的一種新特征“Service Broker”使得查詢通知成為可能。Service Broker把隊(duì)列機(jī)制引入到數(shù)據(jù)庫管理中,它使用一組隊(duì)列與服務(wù)進(jìn)行通訊,而服務(wù)反過來也知道如何往回通訊以調(diào)用相應(yīng)的實(shí)體。其實(shí),這些隊(duì)列和服務(wù)都是一些與表、視圖和存儲(chǔ)過程一樣的類對(duì)象。盡管完全可以在SQL Server內(nèi)使用Service Broker,但是ADO.NET也知道如何與Service Broker進(jìn)行通訊以觸發(fā)這種機(jī)制并且從Service Broker中檢索回通知。
【作者注】Service Broker是SQL Server 2005中新增加的一項(xiàng)重要服務(wù),旨在為日趨流行的面向服務(wù)的架構(gòu)(Service-Oriented Architecture,即“SOA”)在數(shù)據(jù)庫存儲(chǔ)級(jí)提供基礎(chǔ)性支持。
其實(shí),完整的通知架構(gòu)還是比較復(fù)雜的。其中參與的組件可能包括:SQL Server 2005查詢引擎、Service Broker、系統(tǒng)存儲(chǔ)過程sp_DispatcherProc;ADO.NET的SqlNotification類(System.Data.Sql.SqlNotificationRequest)、SqlDependency類(System.Data.Sql.SqlDependency);以及ASP.NET 2.0中新的Cache類(System.Web.Caching.Cache)等等。
下圖1展示了SQL Server 2005中的主動(dòng)通知機(jī)制及其與客戶端ASP.NET頁面交互的示意圖。
?
圖1:SQL Server 2005主動(dòng)通知機(jī)制示意圖
上面的運(yùn)行邏輯大致如下:
(1)SqlCommand類中提供了一個(gè)Notification屬性,用于存儲(chǔ)通知相關(guān)的設(shè)置。當(dāng)SqlCommand執(zhí)行時(shí),會(huì)讓傳遞該執(zhí)行需求的TDS協(xié)議附加上通知的相應(yīng)信息。
(2)SQL Server 2005收到該需求后,為這個(gè)需求注冊(cè)通知,并執(zhí)行該需求自身的SQL語句;
(3)接下來,SQL Server 2005會(huì)監(jiān)控后續(xù)執(zhí)行的DML語法,并確定是否能夠影響前一步返回給前端的數(shù)據(jù)集;一旦有影響,則會(huì)立即發(fā)送一個(gè)消息到Service Broker;
(4)Service Broker的隊(duì)列中有消息后,可能發(fā)生如下情況:
? a)Notification在前端應(yīng)用程序偵聽的隊(duì)列中放入消息,由ADO.NET的下層自動(dòng)讀取消息并觸發(fā)事件;
? b)在Service Broker內(nèi)的消息持續(xù)保留著,較高級(jí)的前端應(yīng)用程序會(huì)自己處理這個(gè)消息。
#p#
如前所述,由于SQL Server 2005的通知機(jī)制在基層上依賴于Services Broker,所以要發(fā)出通知的數(shù)據(jù)庫必須讓Services Broker啟動(dòng)。Services Broker利用SQL Server 2005所提供的隊(duì)列創(chuàng)建異步通知。而通知其實(shí)就是一組Services Broker內(nèi)置好的服務(wù)(也即是標(biāo)準(zhǔn)的消息、發(fā)送的消息及發(fā)送消息的規(guī)則等等)。下圖2中,我們通過SQL Server Management Studio中的對(duì)象資源管理器窗口查看每一個(gè)范例數(shù)據(jù)庫AdventureWorks的“Services Broker”節(jié)點(diǎn)下屬相關(guān)的設(shè)置情況:
?
圖2:SQL Server 2005在Services Broker中已經(jīng)準(zhǔn)備好主動(dòng)式通知設(shè)置情況
前面已經(jīng)提到,我們想通過SQL Server 2005的范例數(shù)據(jù)庫AdventureWorks進(jìn)行試驗(yàn);所以,若要讓程序能夠收到通知,必須先啟動(dòng)該數(shù)據(jù)庫的相應(yīng)服務(wù),同時(shí)還要允許登錄的帳戶訂閱這種查詢通知。下面SQL語句實(shí)現(xiàn)創(chuàng)建相應(yīng)的設(shè)置:
| --啟動(dòng)Service Broker服務(wù)支持 ALTER DATABASE AdventureWorks SET ENABLE_BROKER SELECT * FROM sys.databases --允許某個(gè)賬號(hào)訂閱查詢 |
三、示例分析
有了上面的分析和相應(yīng)的SQL設(shè)置后,現(xiàn)在讓我們來觀察一個(gè)使用SQL Server 2005主動(dòng)式通知機(jī)制的Windows桌面應(yīng)用程序的示例。程序相應(yīng)表單的設(shè)計(jì)界面如下圖3所示:
?
圖3:表單的設(shè)計(jì)界面
| Public Class DeskNotification ??? Dim conn As New SqlConnection(ADONET20.My.Settings.AdventureWorksConnection) System.EventArgs) Handles MyBase.Load ??? Private Sub productListBox_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles productListBox.SelectedIndexChanged ??? Private Sub btnUpdate_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnUpdate.Click ProductID=" & lblId.Text, _ ??? End Sub ??? Public Sub ListProducts() ??????????? '自動(dòng)幫助我們?cè)O(shè)置SqlCommand的Notification屬性所需的SqlNotificationRequest對(duì)象 ??? Private Sub DeskNotification_FormClosing(ByVal sender As System.Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles MyBase.FormClosing ??? End Sub |
#p#
在這個(gè)例子中,我們首先在Global.asax文件內(nèi)的Application_Start事件加入通過SqlDependency類的靜態(tài)方法Start啟動(dòng)監(jiān)聽。注意,這個(gè)Start方法需要傳遞數(shù)據(jù)庫連接字符串。它將完成如下相應(yīng)操作:
◆打開一條新的不經(jīng)過數(shù)據(jù)庫連接池的到SQL Server 2005的連接;
◆在服務(wù)器上創(chuàng)建一個(gè)新的隊(duì)列,并賦予唯一名稱;
◆在該隊(duì)列上創(chuàng)建一個(gè)唯一名稱的服務(wù);
◆在服務(wù)器上創(chuàng)建一個(gè)新的存儲(chǔ)過程,在客戶端不再監(jiān)聽隊(duì)列時(shí),清除掉上述的臨時(shí)創(chuàng)建的各種對(duì)象;
◆偵聽隊(duì)列所收到的更改通知。
【注意】在上面的例子中,盡管你可以通過SqlCommand實(shí)例中的SQL更改記錄,但并沒有自動(dòng)更新列表框內(nèi)的記錄數(shù)據(jù),而是在收到SQL Server記錄改變的通知后,通過事件觸發(fā)指到OnDenpedencyChanged函數(shù)調(diào)用主線程重新執(zhí)行ListProducts方法,從相關(guān)數(shù)據(jù)表讀取更新后的記錄來重設(shè)列表框的內(nèi)容。
四、何時(shí)使用主動(dòng)式通知機(jī)制
查詢通知是針對(duì)于并不經(jīng)常改變的數(shù)據(jù)而設(shè)計(jì)的。最好把它應(yīng)用于服務(wù)器端的應(yīng)用程序(例如ASP.NET或remoting)而不是客戶端應(yīng)用程序(例如Windows表單應(yīng)用程序)。記住,每一個(gè)通知請(qǐng)求都要在SQL Server中注冊(cè)。如果你擁有大量的都有通知請(qǐng)求的客戶端應(yīng)用程序,那么這可能會(huì)導(dǎo)致你的服務(wù)器產(chǎn)生資源問題。鑒于此,微軟推薦,對(duì)于客戶端應(yīng)用程序,你應(yīng)該限制使用查詢通知的最大并行用戶數(shù)不多于十個(gè)。
對(duì)于大規(guī)模應(yīng)用程序來說,查詢通知可能是一種強(qiáng)有力的幫助,而不用簡單地添加越來越多的服務(wù)器以滿足要求。設(shè)想,有一家大型的為成千上百萬用戶提供在線軟件更新服務(wù)的軟件公司。不是使每一個(gè)用戶的更新操作都觸發(fā)服務(wù)器上的另一個(gè)查詢來確定需要哪些組件,而是能夠緩沖查詢結(jié)果并且可以直接從該緩存中服務(wù)匹配的查詢。
對(duì)于較小規(guī)模的情況而言,下拉式列表框是另一種典型的數(shù)據(jù)集;此時(shí)該數(shù)據(jù)集更新的次數(shù)一般不如請(qǐng)求的次數(shù)多。產(chǎn)品列表、州列表、國家列表、供應(yīng)商、銷售人,甚至更多不太需要頻繁改變的信息正是使用上述通知機(jī)制的較好候選。
五、小結(jié)
盡管查詢通知是.NET 2.0中最重要的特征之一,但是目前它仍然難與其它優(yōu)秀特征(例如ASP.NET中的泛型或UI魔術(shù)等)相銜接。然而,無論你使用它來防止針對(duì)于含有數(shù)百個(gè)項(xiàng)的下拉列表框的連續(xù)的反復(fù)查詢,還是使用它來管理基于Web的上百萬的客戶端計(jì)算機(jī)的更新,它都能有效地幫助你減少資源開支。就其最簡單的應(yīng)用來看,借助于ASP.NET OutputCache指令(或通過在你的Web應(yīng)用程序的中間層或Web服務(wù)中構(gòu)建一種復(fù)雜緩沖的機(jī)制),查詢通知可以成為創(chuàng)建可擴(kuò)展的具有響應(yīng)性的應(yīng)用程序的強(qiáng)有力的協(xié)作開發(fā)工具。
【另注】本文基于SQL Server 2005 Express Edition調(diào)試通過。另外,盡管查詢通知可以與SQL Server Express(SSE)一起使用,但是SSE數(shù)據(jù)庫必須是一個(gè)命名的實(shí)例(命名的實(shí)例是安裝選項(xiàng)之一)。
轉(zhuǎn)載于:https://www.cnblogs.com/amylis_chen/p/3234594.html
總結(jié)
以上是生活随笔為你收集整理的浅析SQL Server 2005中的主动式通知机制的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python员工信息管理_用Python
- 下一篇: MSSQL 2005 分页分析及优化(转