程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> 關於C語言 >> ADO.NET 2.0中的查詢通知(2)

ADO.NET 2.0中的查詢通知(2)

編輯:關於C語言

ASP.NET的SqlCacheDependency類(System.Web.Caching.SqlCacheDependency)和OutputCache指示詞會使用SqlDependency實現自動的通知功能。如果ADO.Net客戶端需要對查詢通知擁有更多的控制權,那麼可以使用SqlNotificationRequest並且手工處理Service Broker隊列,實現自己喜歡的處理邏輯。深入解釋Service Broker已經超出了本文的范圍,A First Look at SQL Server 2005 for Developers的示例章節以及Roger Wolter的文章A First Look at SQL Server 2005 Service Broker將對您有所幫助。

在繼續下面的內容之前,明確這一點是十分重要的:當結果集改變時,每個SqlNotificationRequest或者SqlDependency只收到一條通知消息。不管數據改變是由於執行INSERT語句在數據庫上進行了插入、使用DELETE語句刪除了一行或多行,還是使用UPDATE更新了一行或多行,通知消息都是完全一樣的,通知中也不包含任何有關改變的行數或者哪些行被改變的信息。當緩存對象或者用戶應用程序收到這條關於數據改變的消息時只有一種選擇,刷新整個結果集或者重新注冊通知。您不會接收到多條消息,當該條消息引發後,數據庫中的用戶訂閱也就不存在了。此外查詢通知框架的工作前提是:為多種不同事件發送通知總比根本不通知要好。因此不僅僅在結果集改變時會發送通知,刪除或者修改了結果集引用的表、回收數據庫、以及其他一些原因也會發送通知。緩存或程序對通知的響應方式通常是一樣的,即刷新緩存數據並且重新注冊通知。

現在我們已經了解了所有相關的概念和語義,接下來我們將從三個角度深入研究查詢通知是如何工作的:

1.SQL Server的查詢通知是如何實現的?可選的分發器是如何工作的?

2.SqlClIEnt的SqlDependency和SqlNotificationRequest是如何在客戶層/中間層工作的?

3.ASP.Net 2.0是如何支持SqlDependency的?

SQL Server 2005中的查詢通知

在服務器一級,SQL Server分批處理客戶端發送的查詢。每個查詢(可以將查詢看作是SqlCommand.CommandText屬性)只能包含一個批,盡管每個批可以包含多個T-SQL語句。SqlCommand還可以執行存儲過程或者用戶定義的函數,這些對象也可以包含多個T-SQL語句。在SQL Server 2005中,客戶端發送的查詢中還包含了其它三條信息:用於投遞通知的Service Broker的service、通知標識符(一個字符串)、以及通知的超時值。如果查詢請求中存在這三條信息並且查詢包含了SELECT或者EXECUTE語句,那麼SQL Server將“監視”該查詢產生的所有結果集是否因為其他SQL Server會話而改變。如果產生了多個結果集,例如執行了某個存儲過程,那麼SQL Server將“監視”所有的結果集。

那麼我所說的“監視”結果集是指什麼?SQL Server又是如何完成該任務的呢?對結果集的變更檢測是SQL Server數據庫引擎的一部分,使用了SQL Server 2000中用於索引視圖同步的變更檢測機制。在SQL Server 2000中,Microsoft引入了索引視圖的概念。 SQL Server中的視圖包含了對單張表或者多張表的列的查詢。 每個視圖對象都有名稱,可以像使用表名那樣使用視圖名稱,例如:

CREATE VIEW WestCoastAuthors
AS
SELECT * FROM authors
WHERE state IN ('CA', 'WA', 'OR')

現在您就可以使用視圖了,就像在查詢中使用表一樣:

SELECT au_id, au_lname FROM WestCoastAuthors
WHERE au_lname LIKE 'S%'

大多數程序員都很熟悉視圖,但可能並不熟悉索引視圖。在一個非索引視圖中,視圖中的數據並不作為獨立副本而存儲在數據庫中;每次使用視圖時,視圖中包含的查詢將被執行。因此在上面的例子中,將執行獲取WestCoastAuthors結果集的查詢,然後再通過條件判定找出那些我們想要的WestCoastAuthors。索引視圖則存儲了數據副本,因此如果我們將WestCoastAuthors創建成一個索引視圖,我們就擁有兩份authors數據。您現在可以通過兩種方式更新數據,或者通過索引視圖,或者通過原始表。SQL Server因此需要對兩份物理數據存儲的變化進行檢測,從而將一處的變更應用到另一處。這種變更檢測機制和數據庫引擎處理查詢通知時使用的機制是一樣的。

由於變更檢測的這種實現方式,因此並非所有視圖都可以創建索引。那些有關索引視圖的限制條件對於查詢通知也同樣生效。例如:以上面的方式書寫的WestCoastAuthors 視圖就不能創建索引。要想在視圖上創建索引,視圖定義必須使用2部分命名法則,且必須顯式地列出結果集中所有的列名。因此為了創建索引我們來修改一下視圖的定義:

CREATE VIEW WestCoastAuthors
WITH SCHEMABINDING
AS
SELECT au_id, au_lname, au_fname, address, city, state, zip, phone
FROM dbo.authors
WHERE state in ('CA', 'WA', 'OR')

只有遵循了索引視圖規則的那些查詢才可以使用通知。注意:盡管使用了相同的機制來判定是否一個查詢結果集發生了改變,但查詢通知不會導致SQL Server創建數據副本,而索引視圖會。您可以在SQL Server 2005 Books Online中找到有關索引視圖的一系列規則。如果提交了一個附帶通知請求但是違背規則的查詢,SQL Server會立刻發出一個原因為“無效查詢”的通知。可是,通知發布到哪裡呢?

SQL Server 2005使用Service Broker傳遞通知。Service Broker是SQL Server中內置的異步消息隊列功能。查詢通知將使用Service Broker的SERVICE。此處的SERVICE是指異步消息的目的地;可以強制要求消息必須遵循被稱為合同的一組規則。每個Service Broker的SERVICE始終和某個隊列,也就是物理的消息目的地相關聯。查詢通知合同是內置在SQL Server中的,名稱為http://schemas.microsoft.com/SQL/Notifications/PostQueryNotification.

注意:盡管合同在SQL Server中的對象名看似一個URL,但卻與該位置沒有任何聯系。它只是一個對象名,就像dbo.authors是個表名而已。

總而言之,查詢通知消息的目的地可以是任何SERVICE,只要該SERVICE支持相應的合同。使用SQL DDL定義service的語句如下所示:

CREATE QUEUE mynotificationqueue
CREATE SERVICE myservice ON QUEUE mynotificationqueue
([http://schemas.microsoft.com/SQL/Notifications/PostQueryNotification])
GO

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved