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.