Query Notification ASP.NET-ben

A Query Notification az SQL Server 2005 egyik új szolgáltatása. Ez a szolgáltatás csak az SQL Native Client provider-en keresztül érhető el. lényegében arra jó ez a szolgáltatás, hogy csak akkor frissüljün pl a DataSet a Cache-ben, amikor a mögötte található adat is változik és ne akkor amikor lejár a Cache időkorlátja.

A Query Notification a Service Broker-re épül, ezért azt engedélyezni kell azon az adatbázison, amin szeretnénk használni. Az alábbi kód elvégzi ezt:

USE [master];
GO

IF (SELECT is_broker_enabled FROM sys.databases WHERE [name] = 'AdventureWorks') = 0
BEGIN
	ALTER DATABASE AdventureWorks SET ENABLE_BROKER
END
GO

Ezek után létre kell hozni egy Queue-t és egy Service-t:

USE AdventureWorks;
GO
CREATE QUEUE QueryNotificationSampleQueue
GO
CREATE SERVICE QueryNotificationSampleService ON QUEUE QueryNotificationSampleQueue
([http://schemas.microsoft.com/SQL/Notifications/PostQueryNotification])
GO

Ha ezekkel megvagyunk, már csak egy dolog maradt hátra az SQL Serveren.... jogosultság beállitása; a [user] helyére be kell helyettesiteni azt a felhasználót, akinek a nevében csatlakozik az adatbázishoz a webes alaklamazásunk.

GRANT SUBSCRIBE QUERY NOTIFICATIONS TO [user]

Na innen jön az érdekes rész... kétféleképpen lehet az ASP.NET alkamlazásban ezt beállitani. Most az egyszerűbb megközelitést választom:

Hozzunk létre egy ASP.NET Website-ot a Visual Studio-ban, majd a Default.aspx file-ba a következő kódot másoljuk be:

<%@ Page Language="C#" AutoEventWireup="true"  CodeFile="Default.aspx.cs" Inherits="_Default"  %>
<%@ OutputCache SqlDependency="CommandNotification" Duration="99999" VaryByParam="none"  %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
	<head runat="server">
	<title>SQL Query Notification Sample</title> 7
	</head>
	<body>
		<form id="form1" runat="server">
			<div>
				<asp:GridView ID="GridView1" runat="server" DataSourceID="SqlDataSource1">
				</asp:GridView>
				<asp:SqlDataSource ID="SqlDataSource1" runat="server" 
									ConnectionString="<%$ ConnectionStrings:AdventureWorksConnectionString %>" 
									SelectCommand="SELECT [CultureID], [Name], [ModifiedDate] FROM [Production].[Culture]">
				</asp:SqlDataSource>
			</div>
		</form>
	</body>
</html>

Itt egy kicsit elemzzük az OutputCache részt; hozzáadtunk egy SqlDependency tulajdonságot, majd annak értékét CommandNotification-ra állitottuk. Gyakorlatilag ezzel elértük, hogy az ehhez az oldalhoz a Query Notification működjön. A Duration tulajdonságot szándékosan állitottam nagyra, ugyanis nem akarom igazán, hogy a Cache "lejárjon", hanem akkor frissitse, amikor változik az adat mögötte.

Magában ez sajnos még kevés. A Global.asax file-hoz adjuk hozzá a következő kódrészletet:

void Application_Start(object sender, EventArgs e) 
	{
		// Code that runs on application startup
		System.Data.SqlClient.SqlDependency.Start(ConfigurationManager.ConnectionStrings["AdventureWorksConnectionString"].ConnectionString); 
	}

Ha most ezt az oldalt elinditom, akkor 8 rekordot kell látnom a GridView-ban - feltéve, hogy nem változtatattam meg az eredeti tartalmát a Production.Culture táblának. Profiler-rel lekövetve az első oldal betöltését, azt vesszük észre, hogy lefuttatja a lekérdezésünket, de az oldal frissitése esetén már nem. Na akkor most adjunk hozzá egy új rekordot a következő kóddal:

Most töltsük be az oldalt és közben ellenőrizzük a Profiler-t.

 INSERT INTO Production.Culture VALUES ('hu', 'Hungarian', default)

Itt ismét meghivja a lekérdezésünket és láthatjuk, hogy egy exec sp_executesql N'BEGIN CONVERSATION TIMER...... SQL batch is fut folyamatosan. Ez utóbbi a Service Broker Service, ami a Query Notification lelke.

Add comment