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:
1USE [master];
2GO
3
4IF (SELECT is_broker_enabled FROM sys.databases WHERE [name] = 'AdventureWorks') = 0
5BEGIN
6 ALTER DATABASE AdventureWorks SET ENABLE_BROKER
7END
8GO
Ezek után létre kell hozni egy Queue-t és egy Service-t:
1USE AdventureWorks;
2GO
3CREATE QUEUE QueryNotificationSampleQueue
4GO
5CREATE SERVICE QueryNotificationSampleService ON QUEUE QueryNotificationSampleQueue
6([http://schemas.microsoft.com/SQL/Notifications/PostQueryNotification])
7GO
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.
1GRANT 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:
1<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>
2<%@ OutputCache SqlDependency="CommandNotification" Duration="99999" VaryByParam="none" %>
3<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
4<html xmlns="http://www.w3.org/1999/xhtml">
5 <head runat="server">
6 <title>SQL Query Notification Sample</title> 7
7 </head>
8 <body>
9 <form id="form1" runat="server">
10 <div>
11 <asp:GridView ID="GridView1" runat="server" DataSourceID="SqlDataSource1">
12 </asp:GridView>
13 <asp:SqlDataSource ID="SqlDataSource1" runat="server"
14 ConnectionString="<%$ ConnectionStrings:AdventureWorksConnectionString %>"
15 SelectCommand="SELECT [CultureID], [Name], [ModifiedDate] FROM [Production].[Culture]">
16 </asp:SqlDataSource>
17 </div>
18 </form>
19 </body>
20</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:
1void Application_Start(object sender, EventArgs e)
2 {
3 // Code that runs on application startup
4 System.Data.SqlClient.SqlDependency.Start(ConfigurationManager.ConnectionStrings["AdventureWorksConnectionString"].ConnectionString);
5 }
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.
1INSERT 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.