Używanie zależności pamięci podręcznej SQL (VB)
Najprostszą strategią buforowania jest umożliwienie wygaśnięcia buforowanych danych po określonym przedziale czasu. Jednak takie proste podejście oznacza, że buforowane dane nie utrzymują skojarzenia ze źródłowym źródłem danych, co powoduje, że nieaktualne dane przechowywane są zbyt długo lub aktualne dane, które wygasły zbyt szybko. Lepszym rozwiązaniem jest użycie klasy SqlCacheDependency tak, aby dane były buforowane do momentu modyfikacji danych bazowych w bazie danych SQL. W tym samouczku pokazano, jak to zrobić.
Wprowadzenie
Techniki buforowania zbadane w danych buforowania za pomocą obiektu ObjectDataSource i danych buforowania w samouczkach Architektura używały wygaśnięcia opartego na czasie w celu eksmisji danych z pamięci podręcznej po określonym przedziale czasu. Takie podejście jest najprostszym sposobem zrównoważenia wzrostu wydajności buforowania w przypadku nieaktualności danych. Wybierając czas wygaśnięcia x sekund, deweloper strony przyznaje, aby cieszyć się korzyściami z wydajności buforowania tylko x sekund, ale może odpocząć łatwo, że jej dane nigdy nie będą przestarzałe niż maksymalnie x sekund. Oczywiście w przypadku danych statycznych x można rozszerzyć na okres istnienia aplikacji internetowej, jak znaleziono w samouczku Buforowanie danych podczas uruchamiania aplikacji .
W przypadku buforowania danych bazy danych wygaśnięcie oparte na czasie jest często wybierane pod kątem łatwości użycia, ale często jest nieodpowiednim rozwiązaniem. W idealnym przypadku dane bazy danych pozostaną buforowane do momentu modyfikacji danych bazowych w bazie danych; tylko wtedy pamięć podręczna zostanie eksmitowana. Takie podejście maksymalizuje korzyści z wydajności buforowania i minimalizuje czas trwania nieaktualnych danych. Jednak w celu korzystania z tych korzyści musi istnieć system, który wie, kiedy bazowe dane bazy danych zostały zmodyfikowane i eksmituje odpowiednie elementy z pamięci podręcznej. Przed ASP.NET 2.0 deweloperzy stron byli odpowiedzialni za wdrożenie tego systemu.
ASP.NET 2.0 zapewnia klasę i niezbędną SqlCacheDependency
infrastrukturę do określenia, kiedy nastąpiła zmiana w bazie danych, aby można było eksmitować odpowiednie buforowane elementy. Istnieją dwie techniki określania, kiedy dane bazowe uległy zmianie: powiadamianie i sondowanie. Po omówieniu różnic między powiadomieniami i sondowaniem utworzymy infrastrukturę niezbędną do obsługi sondowania, a następnie zbadamy, jak używać SqlCacheDependency
klasy w scenariuszach deklaratywnych i programowych.
Opis powiadomień i sondowania
Istnieją dwie techniki, których można użyć do określenia, kiedy dane w bazie danych zostały zmodyfikowane: powiadomienie i sondowanie. Dzięki powiadomieniu baza danych automatycznie powiadamia środowisko uruchomieniowe ASP.NET, gdy wyniki określonego zapytania zostały zmienione od czasu ostatniego wykonania zapytania, w którym to momencie są eksmitowane buforowane elementy skojarzone z zapytaniem. W przypadku sondowania serwer bazy danych przechowuje informacje o tym, kiedy ostatnio zaktualizowano określone tabele. Środowisko uruchomieniowe ASP.NET okresowo sonduje bazę danych, aby sprawdzić, jakie tabele uległy zmianie od czasu ich wprowadzenia do pamięci podręcznej. Te tabele, których dane zostały zmodyfikowane, mają skojarzone elementy pamięci podręcznej eksmitowane.
Opcja powiadomienia wymaga mniejszej konfiguracji niż sondowania i jest bardziej szczegółowa, ponieważ śledzi zmiany na poziomie zapytania, a nie na poziomie tabeli. Niestety powiadomienia są dostępne tylko w pełnych wersjach programu Microsoft SQL Server 2005 (tj. wydaniach innych niż Express). Można jednak użyć opcji sondowania dla wszystkich wersji programu Microsoft SQL Server z wersji od 7.0 do 2005. Ponieważ te samouczki korzystają z wersji Express SQL Server 2005, skoncentrujemy się na konfigurowaniu i używaniu opcji sondowania. Zapoznaj się z sekcją Dalsze informacje na końcu tego samouczka, aby uzyskać więcej zasobów dotyczących możliwości powiadomień SQL Server 2005.
W przypadku sondowania baza danych musi być skonfigurowana tak, aby zawierała tabelę o nazwie AspNet_SqlCacheTablesForChangeNotification
z trzema kolumnami — tableName
, notificationCreated
i changeId
. Ta tabela zawiera wiersz dla każdej tabeli zawierającej dane, które mogą być potrzebne do użycia w zależności od pamięci podręcznej SQL w aplikacji internetowej. Kolumna tableName
określa nazwę tabeli, określając notificationCreated
datę i godzinę dodania wiersza do tabeli. Kolumna changeId
jest typu int
i ma początkową wartość 0. Jego wartość jest zwiększana wraz z każdą modyfikacją tabeli.
Oprócz AspNet_SqlCacheTablesForChangeNotification
tabeli baza danych musi również uwzględniać wyzwalacze dla każdej z tabel, które mogą pojawić się w zależności od pamięci podręcznej SQL. Te wyzwalacze są wykonywane za każdym razem, gdy wiersz jest wstawiany, aktualizowany lub usuwany i zwiększa wartość tabeli changeId
w elemecie AspNet_SqlCacheTablesForChangeNotification
.
Środowisko uruchomieniowe ASP.NET śledzi bieżącą wartość changeId
tabeli podczas buforowania danych przy użyciu SqlCacheDependency
obiektu. Baza danych jest okresowo sprawdzana, a wszystkie SqlCacheDependency
obiekty, których changeId
wartość w bazie danych różni się od wartości, są eksmitowane, ponieważ inna changeId
wartość wskazuje, że nastąpiła zmiana tabeli od czasu buforowania danych.
Krok 1. Eksplorowanieaspnet_regsql.exe
programu wiersza polecenia
W przypadku podejścia sondowania baza danych musi być skonfigurowana tak, aby zawierała infrastrukturę opisaną powyżej: wstępnie zdefiniowaną tabelę (AspNet_SqlCacheTablesForChangeNotification
), kilka procedur składowanych i wyzwalacze dla każdej z tabel, które mogą być używane w zależnościach pamięci podręcznej SQL w aplikacji internetowej. Te tabele, procedury składowane i wyzwalacze można utworzyć za pomocą programu aspnet_regsql.exe
wiersza polecenia , który znajduje się w folderze $WINDOWS$\Microsoft.NET\Framework\version
. Aby utworzyć tabelę AspNet_SqlCacheTablesForChangeNotification
i skojarzone procedury składowane, uruchom następujące polecenie w wierszu polecenia:
/* For SQL Server authentication... */
aspnet_regsql.exe -S server -U user -P password -d database -ed
/* For Windows Authentication... */
aspnet_regsql.exe -S server -E -d database -ed
Uwaga
Aby wykonać te polecenia, określone dane logowania bazy danych muszą znajdować się w db_securityadmin
rolach i db_ddladmin
.
Aby na przykład dodać infrastrukturę do sondowania do bazy danych microsoft SQL Server o nazwie na serwerze bazy danych o nazwie pubs
ScottsServer
przy użyciu uwierzytelniania systemu Windows, przejdź do odpowiedniego katalogu i w wierszu polecenia wprowadź:
aspnet_regsql.exe -S ScottsServer -E -d pubs -ed
Po dodaniu infrastruktury na poziomie bazy danych musimy dodać wyzwalacze do tych tabel, które będą używane w zależnościach pamięci podręcznej SQL. aspnet_regsql.exe
Ponownie użyj programu wiersza polecenia, ale określ nazwę tabeli przy użyciu przełącznika -t
i zamiast używać przełącznika -ed
, -et
w następujący sposób:
/* For SQL Server authentication... */
aspnet_regsql.exe -S <i>server</i>
-U <i>user</i> -P <i>password</i> -d <i>database</i> -t <i>tableName</i> -et
/* For Windows Authentication... */
aspnet_regsql.exe -S <i>server</i>
-E -d <i>database</i> -t <i>tableName</i> -et
Aby dodać wyzwalacze do authors
tabel i titles
w bazie danych w pubs
usłudze ScottsServer
, użyj:
aspnet_regsql.exe -S ScottsServer -E -d pubs -t authors -et
aspnet_regsql.exe -S ScottsServer -E -d pubs -t titles -et
Na potrzeby tego samouczka dodaj wyzwalacze do Products
tabel , Categories
i Suppliers
. Przyjrzymy się określonej składni wiersza polecenia w kroku 3.
Krok 2. Odwoływanie się do bazy danych microsoft SQL Server 2005 Express Edition w programieApp_Data
Program aspnet_regsql.exe
wiersza polecenia wymaga nazwy bazy danych i serwera w celu dodania niezbędnej infrastruktury sondowania. Ale jaka jest nazwa bazy danych i serwera bazy danych microsoft SQL Server 2005 Express, która znajduje się w folderzeApp_Data
? Zamiast odnajdywać nazwy baz danych i serwerów, okazało się, że najprostszym podejściem jest dołączenie bazy danych do localhost\SQLExpress
wystąpienia bazy danych i zmiana nazwy danych przy użyciu SQL Server Management Studio. Jeśli masz jedną z pełnych wersji SQL Server 2005 zainstalowanych na komputerze, prawdopodobnie masz już zainstalowane SQL Server Management Studio na komputerze. Jeśli masz tylko wersję Express, możesz pobrać bezpłatną aplikację Microsoft SQL Server Management Studio.
Zacznij od zamknięcia programu Visual Studio. Następnie otwórz SQL Server Management Studio i wybierz połączenie z serwerem localhost\SQLExpress
przy użyciu uwierzytelniania systemu Windows.
Rysunek 1. Dołączanie do localhost\SQLExpress
serwera
Po nawiązaniu połączenia z serwerem program Management Studio wyświetli serwer i będzie miał podfoldery baz danych, zabezpieczeń itd. Kliknij prawym przyciskiem myszy folder Bazy danych i wybierz opcję Dołącz. Spowoduje to wyświetlenie okna dialogowego Dołączanie baz danych (zobacz Rysunek 2). Kliknij przycisk Dodaj i wybierz NORTHWND.MDF
folder bazy danych w folderze aplikacji App_Data
internetowej.
Rysunek 2. Dołączanie NORTHWND.MDF
bazy danych z App_Data
folderu (kliknij, aby wyświetlić obraz pełnowymiarowy)
Spowoduje to dodanie bazy danych do folderu Databases. Nazwa bazy danych może być pełną ścieżką do pliku bazy danych lub pełną ścieżką poprzedzaną identyfikatorem GUID. Aby uniknąć konieczności wpisywania tej długiej nazwy bazy danych podczas korzystania z narzędzia wiersza polecenia aspnet_regsql.exe, zmień nazwę bazy danych na bardziej przyjazną dla człowieka, klikając prawym przyciskiem myszy bazę danych po prostu dołączoną i wybierając polecenie Zmień nazwę. Zmieniono nazwę bazy danych na DataTutorials .
Rysunek 3. Zmiana nazwy dołączonej bazy danych na bardziej Human-Friendly nazwa
Krok 3. Dodawanie infrastruktury sondowania do bazy danych Northwind
Teraz, gdy dołączyliśmy NORTHWND.MDF
bazę danych z App_Data
folderu, możemy dodać infrastrukturę sondowania. Zakładając, że zmieniono nazwę bazy danych na DataTutorials, uruchom następujące cztery polecenia:
aspnet_regsql.exe -S localhost\SQLExpress -E -d DataTutorials -ed
aspnet_regsql.exe -S localhost\SQLExpress -E -d DataTutorials -t Products -et
aspnet_regsql.exe -S localhost\SQLExpress -E -d DataTutorials -t Categories -et
aspnet_regsql.exe -S localhost\SQLExpress -E -d DataTutorials -t Suppliers -et
Po uruchomieniu tych czterech poleceń kliknij prawym przyciskiem myszy nazwę bazy danych w programie Management Studio, przejdź do podmenu Zadania i wybierz polecenie Odłącz. Następnie zamknij program Management Studio i otwórz ponownie program Visual Studio.
Po ponownym otwarciu programu Visual Studio przejdź do bazy danych za pośrednictwem Eksploratora serwera. Zanotuj nową tabelę (AspNet_SqlCacheTablesForChangeNotification
), nowe procedury składowane i wyzwalacze w Products
tabelach , Categories
i Suppliers
.
Rysunek 4. Baza danych zawiera teraz niezbędną infrastrukturę sondowania
Krok 4. Konfigurowanie usługi sondowania
Po utworzeniu wymaganych tabel, wyzwalaczy i procedur składowanych w bazie danych ostatnim krokiem jest skonfigurowanie usługi sondowania, która odbywa się przez Web.config
określenie baz danych do użycia i częstotliwość sondowania w milisekundach. Poniższe znaczniki sonduje bazę danych Northwind raz na sekundę.
<?xml version="1.0"?>
<configuration>
<connectionStrings>
<add name="NORTHWNDConnectionString" connectionString=
"Data Source=.\SQLEXPRESS;AttachDbFilename=|DataDirectory|\NORTHWND.MDF;
Integrated Security=True;User Instance=True"
providerName="System.Data.SqlClient"/>
</connectionStrings>
<system.web>
...
<!-- Configure the polling service used for SQL cache dependencies -->
<caching>
<sqlCacheDependency enabled="true" pollTime="1000" >
<databases>
<add name="NorthwindDB"
connectionStringName="NORTHWNDConnectionString" />
</databases>
</sqlCacheDependency>
</caching>
</system.web>
</configuration>
Wartość name
w <add>
elemecie ( NorthwindDB ) kojarzy nazwę czytelną dla człowieka z określoną bazą danych. Podczas pracy z zależnościami pamięci podręcznej SQL musimy odwoływać się do nazwy bazy danych zdefiniowanej tutaj, a także tabeli, na podstawie których są buforowane dane. Zobaczymy, jak za pomocą SqlCacheDependency
klasy programowo skojarzyć zależności pamięci podręcznej SQL z zapisanymi w pamięci podręcznej danymi w kroku 6.
Po ustanowieniu zależności pamięci podręcznej SQL system sondowania połączy się z bazami danych zdefiniowanymi w <databases>
elementach co pollTime
milisekundy i wykona procedurę AspNet_SqlCachePollingStoredProcedure
składowaną. Ta procedura składowana — która została dodana z powrotem w kroku 3 przy użyciu narzędzia wiersza polecenia — zwraca tableName
wartości i changeId
dla każdego rekordu aspnet_regsql.exe
w AspNet_SqlCacheTablesForChangeNotification
programie . Nieaktualne zależności pamięci podręcznej SQL są eksmitowane z pamięci podręcznej.
Ustawienie pollTime
wprowadza kompromis między wydajnością a nieaktualnością danych. Mała pollTime
wartość zwiększa liczbę żądań do bazy danych, ale szybciej eksmituje nieaktualne dane z pamięci podręcznej. Większa pollTime
wartość zmniejsza liczbę żądań bazy danych, ale zwiększa opóźnienie między zmianą danych zaplecza a usunięciem powiązanych elementów pamięci podręcznej. Na szczęście żądanie bazy danych wykonuje prostą procedurę składowaną, która zwraca tylko kilka wierszy z prostej, lekkiej tabeli. Jednak eksperymentuj z różnymi pollTime
wartościami, aby znaleźć idealną równowagę między dostępem do bazy danych a nieaktualnością danych dla aplikacji. Najmniejsza pollTime
dozwolona wartość to 500.
Uwaga
Powyższy przykład zawiera pojedynczą pollTime
wartość w <sqlCacheDependency>
elemecie, ale opcjonalnie można określić pollTime
wartość w <add>
elemecie. Jest to przydatne, jeśli określono wiele baz danych i chcesz dostosować częstotliwość sondowania na bazę danych.
Krok 5. Deklaratywna praca z zależnościami pamięci podręcznej SQL
W krokach od 1 do 4 przyjrzeliśmy się, jak skonfigurować niezbędną infrastrukturę bazy danych i skonfigurować system sondowania. Dzięki tej infrastrukturze możemy teraz dodawać elementy do pamięci podręcznej danych ze skojarzona zależność pamięci podręcznej SQL przy użyciu technik programowych lub deklaratywnych. W tym kroku sprawdzimy, jak deklaratywnie pracować z zależnościami pamięci podręcznej SQL. W kroku 6 przyjrzymy się programowej metodzie.
Samouczek Buforowanie danych za pomocą obiektu ObjectDataSource omówił funkcje deklaratywnego buforowania obiektu ObjectDataSource. Po prostu ustawiając EnableCaching
właściwość na True
i CacheDuration
właściwość na jakiś interwał czasu, obiekt ObjectDataSource automatycznie buforuje dane zwrócone z jego obiektu bazowego dla określonego interwału. Obiekt ObjectDataSource może również używać co najmniej jednej zależności pamięci podręcznej SQL.
Aby zademonstrować użycie zależności pamięci podręcznej SQL deklaratywnie, otwórz SqlCacheDependencies.aspx
stronę w Caching
folderze i przeciągnij element GridView z przybornika do Projektant. Ustaw element GridView na ID
ProductsDeclarative
i z jego tagu inteligentnego wybierz powiązanie go z nowym obiektem ObjectDataSource o nazwie ProductsDataSourceDeclarative
.
Rysunek 5. Tworzenie nowego obiektu ObjectDataSource Nazwane ProductsDataSourceDeclarative
(kliknij, aby wyświetlić obraz pełnowymiarowy)
Skonfiguruj obiekt ObjectDataSource do użycia ProductsBLL
klasy i ustaw listę rozwijaną na karcie SELECT na GetProducts()
wartość . Na karcie UPDATE wybierz przeciążenie z trzema UpdateProduct
parametrami wejściowymi — productName
, unitPrice
i productID
. Ustaw listy rozwijane na wartość (Brak) na kartach INSERT i DELETE.
Rysunek 6. Użycie przeciążenia UpdateProduct z trzema parametrami wejściowymi (kliknij, aby wyświetlić obraz pełnowymiarowy)
Rysunek 7. Ustawianie listy Drop-Down na (Brak) dla kart INSERT i DELETE (Kliknij, aby wyświetlić obraz pełnowymiarowy)
Po ukończeniu pracy Kreatora konfigurowania źródła danych program Visual Studio utworzy pola BoundFields i CheckBoxFields w elemecie GridView dla każdego pola danych. Usuń wszystkie pola, ale ProductName
, CategoryName
i UnitPrice
i sformatuj te pola zgodnie z potrzebami. W tagu inteligentnym GridView zaznacz pola wyboru Włącz stronicowanie, Włącz sortowanie i Włącz edytowanie. Program Visual Studio ustawi właściwość ObjectDataSource na OldValuesParameterFormatString
original_{0}
. Aby funkcja edycji elementu GridView działała prawidłowo, usuń tę właściwość całkowicie ze składni deklaratywnej lub ustaw ją z powrotem na wartość domyślną . {0}
Na koniec dodaj kontrolkę Etykieta sieci Web nad kontrolką GridView i ustaw jej ID
właściwość na ODSEvents
i jej EnableViewState
właściwość na False
. Po wprowadzeniu tych zmian znacznik deklaratywny strony powinien wyglądać podobnie do poniższego. Należy pamiętać, że wprowadzono wiele dostosowań estetycznych w polach GridView, które nie są niezbędne do zademonstrowania funkcji zależności pamięci podręcznej SQL.
<asp:Label ID="ODSEvents" runat="server" EnableViewState="False" />
<asp:GridView ID="ProductsDeclarative" runat="server"
AutoGenerateColumns="False" DataKeyNames="ProductID"
DataSourceID="ProductsDataSourceDeclarative"
AllowPaging="True" AllowSorting="True">
<Columns>
<asp:CommandField ShowEditButton="True" />
<asp:TemplateField HeaderText="Product" SortExpression="ProductName">
<EditItemTemplate>
<asp:TextBox ID="ProductName" runat="server"
Text='<%# Bind("ProductName") %>' />
<asp:RequiredFieldValidator ID="RequiredFieldValidator1"
ControlToValidate="ProductName" Display="Dynamic"
ErrorMessage="You must provide a name for the product."
SetFocusOnError="True"
runat="server">*</asp:RequiredFieldValidator>
</EditItemTemplate>
<ItemTemplate>
<asp:Label ID="Label2" runat="server"
Text='<%# Bind("ProductName") %>' />
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField DataField="CategoryName" HeaderText="Category"
ReadOnly="True" SortExpression="CategoryName" />
<asp:TemplateField HeaderText="Price" SortExpression="UnitPrice">
<EditItemTemplate>
$<asp:TextBox ID="UnitPrice" runat="server" Columns="8"
Text='<%# Bind("UnitPrice", "{0:N2}") %>'></asp:TextBox>
<asp:CompareValidator ID="CompareValidator1" runat="server"
ControlToValidate="UnitPrice"
ErrorMessage="You must enter a valid currency value with
no currency symbols. Also, the value must be greater than
or equal to zero."
Operator="GreaterThanEqual" SetFocusOnError="True"
Type="Currency" Display="Dynamic"
ValueToCompare="0">*</asp:CompareValidator>
</EditItemTemplate>
<ItemStyle HorizontalAlign="Right" />
<ItemTemplate>
<asp:Label ID="Label1" runat="server"
Text='<%# Bind("UnitPrice", "{0:c}") %>' />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
<asp:ObjectDataSource ID="ProductsDataSourceDeclarative" runat="server"
SelectMethod="GetProducts" TypeName="ProductsBLL"
UpdateMethod="UpdateProduct">
<UpdateParameters>
<asp:Parameter Name="productName" Type="String" />
<asp:Parameter Name="unitPrice" Type="Decimal" />
<asp:Parameter Name="productID" Type="Int32" />
</UpdateParameters>
</asp:ObjectDataSource>
Następnie utwórz procedurę obsługi zdarzeń dla zdarzenia ObjectDataSource Selecting
i dodaj w nim następujący kod:
Protected Sub ProductsDataSourceDeclarative_Selecting _
(sender As Object, e As ObjectDataSourceSelectingEventArgs) _
Handles ProductsDataSourceDeclarative.Selecting
ODSEvents.Text = "-- Selecting event fired"
End Sub
Pamiętaj, że zdarzenie ObjectDataSource Selecting
jest uruchamiane tylko w przypadku pobierania danych z jego obiektu bazowego. Jeśli obiekt ObjectDataSource uzyskuje dostęp do danych z własnej pamięci podręcznej, to zdarzenie nie zostanie wyzwolone.
Teraz odwiedź tę stronę za pośrednictwem przeglądarki. Ponieważ jeszcze zaimplementowaliśmy jakiekolwiek buforowanie, za każdym razem, gdy strona, sortowanie lub edytowanie siatki strona powinna wyświetlić tekst "Wybranie zdarzenia wyzwolonego, jak pokazano na rysunku 8.
Rysunek 8. Zdarzenie ObjectDataSource Selecting
jest wyzwalane za każdym razem, gdy element GridView jest stronicowany, edytowany lub posortowany (kliknij, aby wyświetlić obraz pełnowymiarowy)
Jak pokazano w samouczku Buforowanie danych za pomocą obiektu ObjectDataSource , ustawienie EnableCaching
właściwości powoduje True
, że właściwość ObjectDataSource będzie buforować swoje dane przez czas określony przez jego CacheDuration
właściwość. Obiekt ObjectDataSource ma SqlCacheDependency
również właściwość, która dodaje co najmniej jedną zależność pamięci podręcznej SQL do buforowanych danych przy użyciu wzorca:
databaseName1:tableName1;databaseName2:tableName2;...
Gdzie databaseName to nazwa bazy danych określona w name
atrybucie <add>
elementu w , Web.config
a tableName jest nazwą tabeli bazy danych. Aby na przykład utworzyć obiekt ObjectDataSource, który buforuje dane na czas nieokreślony na podstawie zależności pamięci podręcznej SQL od tabeli Northwind s Products
, ustaw właściwość ObjectDataSource EnableCaching
na True
i jej SqlCacheDependency
właściwość na NorthwindDB:Products .
Uwaga
Można użyć zależności pamięci podręcznej SQL i wygaśnięcia opartego na czasie, ustawiając wartość EnableCaching
True
na , CacheDuration
na interwał czasu oraz SqlCacheDependency
na nazwy baz danych i tabeli. Obiekt ObjectDataSource wykluczy swoje dane po osiągnięciu wygaśnięcia opartego na czasie lub gdy system sondowania zauważa, że bazowe dane bazy danych uległy zmianie, w zależności od tego, co nastąpi wcześniej.
Element GridView w programie SqlCacheDependencies.aspx
wyświetla dane z dwóch tabel — Products
i Categories
(pole produktu CategoryName
jest pobierane za pośrednictwem elementu JOIN
.Categories
W związku z tym chcemy określić dwie zależności pamięci podręcznej SQL: NorthwindDB:Products; NorthwindDB:Categories .
Rysunek 9. Konfigurowanie obiektu ObjectDataSource do obsługi buforowania przy użyciu zależności Products
pamięci podręcznej SQL i Categories
(kliknij, aby wyświetlić obraz o pełnym rozmiarze)
Po skonfigurowaniu obiektu ObjectDataSource do obsługi buforowania ponownie przejdź do strony za pośrednictwem przeglądarki. Ponownie tekst "Wyzwolone zdarzenie wybierania powinno pojawić się podczas pierwszej wizyty na stronie, ale powinien odejść podczas stronicowania, sortowania lub klikania przycisków Edytuj lub Anuluj. Dzieje się tak dlatego, że po załadowaniu danych do pamięci podręcznej ObjectDataSource pozostają tam do momentu Products
modyfikacji tabel lub Categories
lub zaktualizowania danych za pośrednictwem kontrolki GridView.
Po stronicowaniu przez siatkę i zaniesieniu braku tekstu "Wybieranie zdarzenia wyzwolonego tekstu otwórz nowe okno przeglądarki i przejdź do samouczka Podstawy w sekcji Edytowanie, Wstawianie i Usuwanie (~/EditInsertDelete/Basics.aspx
). Zaktualizuj nazwę lub cenę produktu. Następnie w oknie pierwszej przeglądarki wyświetl inną stronę danych, posortuj siatkę lub kliknij przycisk Edytuj wiersz. Tym razem zdarzenie wyboru powinno zostać ponownie wyzwolone, ponieważ bazowe dane bazy danych zostały zmodyfikowane (patrz Rysunek 10). Jeśli tekst nie jest wyświetlany, poczekaj chwilę i spróbuj ponownie. Pamiętaj, że usługa sondowania sprawdza zmiany Products
w tabeli co pollTime
milisekundy, dlatego występuje opóźnienie między aktualizowaniem danych bazowych a eksmitowaniem buforowanych danych.
Rysunek 10. Modyfikowanie tabeli products eksmituje buforowane dane produktu (kliknij, aby wyświetlić obraz pełnowymiarowy)
Krok 6. Programowe praca z klasąSqlCacheDependency
W samouczku Buforowanie danych w architekturze przedstawiono korzyści wynikające z używania oddzielnej warstwy buforowania w architekturze, a nie ściśle sprzężenia buforowania z obiektem ObjectDataSource. W tym samouczku utworzyliśmy klasę ProductsCL
, która programowo współpracuje z pamięcią podręczną danych. Aby korzystać z zależności pamięci podręcznej SQL w warstwie buforowania, użyj SqlCacheDependency
klasy .
W systemie SqlCacheDependency
sondowania obiekt musi być skojarzony z określoną bazą danych i parą tabel. Na przykład poniższy kod tworzy SqlCacheDependency
obiekt na podstawie tabeli bazy danych Products
Northwind:
Dim productsTableDependency As _
New Caching.SqlCacheDependency("NorthwindDB", "Products")
Dwa parametry SqlCacheDependency
wejściowe konstruktora to odpowiednio nazwy baz danych i tabel. Podobnie jak we właściwości ObjectDataSource SqlCacheDependency
, używana nazwa bazy danych jest taka sama jak wartość określona w name
atrybucie <add>
elementu w Web.config
. Nazwa tabeli to rzeczywista nazwa tabeli bazy danych.
Aby skojarzyć SqlCacheDependency
element z elementem dodanym do pamięci podręcznej danych, użyj jednego z Insert
przeciążeń metody akceptujących zależność. Poniższy kod dodaje wartość do pamięci podręcznej danych przez nieokreślony czas trwania, ale kojarzy go z tabelą SqlCacheDependency
Products
. Krótko mówiąc, wartość pozostanie w pamięci podręcznej, dopóki nie zostanie eksmitowana z powodu ograniczeń pamięci lub ponieważ system sondowania wykrył, że Products
tabela uległa zmianie od czasu jego buforowania.
Dim productsTableDependency As _
New Caching.SqlCacheDependency("NorthwindDB", "Products")
Cache.Insert(key, _
value, _
productsTableDependency, _
System.Web.Caching.Cache.NoAbsoluteExpiration, _
System.Web.Caching.Cache.NoSlidingExpiration)
Klasa warstwy ProductsCL
buforowania buforuje obecnie dane z Products
tabeli przy użyciu wygaśnięcia na podstawie czasu 60 sekund. Zaktualizujmy tę klasę, aby zamiast tego korzystała z zależności pamięci podręcznej SQL. Metoda ProductsCL
klasy s AddCacheItem
, która jest odpowiedzialna za dodawanie danych do pamięci podręcznej, obecnie zawiera następujący kod:
Private Sub AddCacheItem(ByVal rawKey As String, ByVal value As Object)
Dim DataCache As System.Web.Caching.Cache = HttpRuntime.Cache
' Make sure MasterCacheKeyArray(0) is in the cache - if not, add it
If DataCache(MasterCacheKeyArray(0)) Is Nothing Then
DataCache(MasterCacheKeyArray(0)) = DateTime.Now
End If
' Add a CacheDependency
Dim dependency As _
New Caching.CacheDependency(Nothing, MasterCacheKeyArray)
DataCache.Insert(GetCacheKey(rawKey), value, dependency, _
DateTime.Now.AddSeconds(CacheDuration), _
Caching.Cache.NoSlidingExpiration)
End Sub
Zaktualizuj ten kod, aby użyć SqlCacheDependency
obiektu zamiast zależności pamięci podręcznej MasterCacheKeyArray
:
Private Sub AddCacheItem(ByVal rawKey As String, ByVal value As Object)
Dim DataCache As System.Web.Caching.Cache = HttpRuntime.Cache
' Add the SqlCacheDependency objects for Products
Dim productsTableDependency As New _
Caching.SqlCacheDependency("NorthwindDB", "Products")
DataCache.Insert(GetCacheKey(rawKey), value, productsTableDependency, _
Cache.NoAbsoluteExpiration, Caching.Cache.NoSlidingExpiration)
End Sub
Aby przetestować tę funkcję, dodaj element GridView do strony poniżej istniejącej ProductsDeclarative
kontrolki GridView. Ustaw ten nowy element GridView na ID
ProductsProgrammatic
i, za pomocą tagu inteligentnego, powiąż go z nowym obiektem ObjectDataSource o nazwie ProductsDataSourceProgrammatic
. Skonfiguruj obiekt ObjectDataSource do użycia ProductsCL
klasy, ustawiając listy rozwijane na kartach SELECT i UPDATE odpowiednio na GetProducts
i UpdateProduct
.
Rysunek 11. Konfigurowanie obiektu ObjectDataSource do używania ProductsCL
klasy (kliknij, aby wyświetlić obraz pełnowymiarowy)
Rysunek 12. Wybierz metodę GetProducts
z listy Drop-Down SELECT Tab (Kliknij, aby wyświetlić obraz pełnowymiarowy)
Rysunek 13. Wybierz metodę UpdateProduct z listy Drop-Down kart AKTUALIZACJI (kliknij, aby wyświetlić obraz pełnowymiarowy)
Po ukończeniu pracy Kreatora konfigurowania źródła danych program Visual Studio utworzy pola BoundFields i CheckBoxFields w elemecie GridView dla każdego pola danych. Podobnie jak w przypadku pierwszego elementu GridView dodanego do tej strony, usuń wszystkie pola, ale ProductName
, CategoryName
i UnitPrice
sformatuj te pola zgodnie z potrzebami. W tagu inteligentnym GridView zaznacz pola wyboru Włącz stronicowanie, Włącz sortowanie i Włącz edytowanie. Podobnie jak w przypadku ProductsDataSourceDeclarative
obiektu ObjectDataSource, program Visual Studio ustawi ProductsDataSourceProgrammatic
właściwość ObjectDataSource OldValuesParameterFormatString
na original_{0}
. Aby funkcja edycji elementu GridView działała prawidłowo, ustaw tę właściwość z powrotem na {0}
(lub całkowicie usuń przypisanie właściwości ze składni deklaratywnej).
Po wykonaniu tych zadań wynikowe znaczniki deklaratywne GridView i ObjectDataSource powinny wyglądać następująco:
<asp:GridView ID="ProductsProgrammatic" runat="server"
AutoGenerateColumns="False" DataKeyNames="ProductID"
DataSourceID="ProductsDataSourceProgrammatic" AllowPaging="True"
AllowSorting="True">
<Columns>
<asp:CommandField ShowEditButton="True" />
<asp:TemplateField HeaderText="Product" SortExpression="ProductName">
<EditItemTemplate>
<asp:TextBox ID="ProductName" runat="server"
Text='<%# Bind("ProductName") %>' />
<asp:RequiredFieldValidator ID="RequiredFieldValidator1"
ControlToValidate="ProductName" Display="Dynamic"
ErrorMessage="You must provide a name for the product."
SetFocusOnError="True"
runat="server">*</asp:RequiredFieldValidator>
</EditItemTemplate>
<ItemTemplate>
<asp:Label ID="Label2" runat="server"
Text='<%# Bind("ProductName") %>' />
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField DataField="CategoryName" HeaderText="Category"
ReadOnly="True" SortExpression="CategoryName" />
<asp:TemplateField HeaderText="Price" SortExpression="UnitPrice">
<EditItemTemplate>
$<asp:TextBox ID="UnitPrice" runat="server" Columns="8"
Text='<%# Bind("UnitPrice", "{0:N2}") %>'></asp:TextBox>
<asp:CompareValidator ID="CompareValidator1" runat="server"
ControlToValidate="UnitPrice" Display="Dynamic"
ErrorMessage="You must enter a valid currency value with no
currency symbols. Also, the value must be greater than
or equal to zero."
Operator="GreaterThanEqual" SetFocusOnError="True"
Type="Currency" ValueToCompare="0">*</asp:CompareValidator>
</EditItemTemplate>
<ItemStyle HorizontalAlign="Right" />
<ItemTemplate>
<asp:Label ID="Label1" runat="server"
Text='<%# Bind("UnitPrice", "{0:c}") %>' />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
<asp:ObjectDataSource ID="ProductsDataSourceProgrammatic" runat="server"
OldValuesParameterFormatString="{0}" SelectMethod="GetProducts"
TypeName="ProductsCL" UpdateMethod="UpdateProduct">
<UpdateParameters>
<asp:Parameter Name="productName" Type="String" />
<asp:Parameter Name="unitPrice" Type="Decimal" />
<asp:Parameter Name="productID" Type="Int32" />
</UpdateParameters>
</asp:ObjectDataSource>
Aby przetestować zależność pamięci podręcznej SQL w warstwie buforowania, ustaw punkt przerwania w ProductCL
metodzie klasy s AddCacheItem
, a następnie rozpocznij debugowanie. Podczas pierwszej wizyty SqlCacheDependencies.aspx
punkt przerwania powinien zostać trafiony, ponieważ dane są żądane po raz pierwszy i umieszczone w pamięci podręcznej. Następnie przejdź do innej strony w elemecie GridView lub posortuj jedną z kolumn. Powoduje to ponowne zapytanie danych elementu GridView, ale dane powinny znajdować się w pamięci podręcznej, ponieważ Products
tabela bazy danych nie została zmodyfikowana. Jeśli dane nie znajdują się wielokrotnie w pamięci podręcznej, upewnij się, że na komputerze jest wystarczająca ilość pamięci i spróbuj ponownie.
Po stronicowaniu za pomocą kilku stron kontrolki GridView otwórz drugie okno przeglądarki i przejdź do samouczka Podstawy w sekcji Edytowanie, Wstawianie i Usuwanie (~/EditInsertDelete/Basics.aspx
). Zaktualizuj rekord z tabeli Products, a następnie w pierwszym oknie przeglądarki wyświetl nową stronę lub kliknij jeden z nagłówków sortowania.
W tym scenariuszu zobaczysz jedną z dwóch rzeczy: zostanie trafiony punkt przerwania wskazujący, że buforowane dane zostały eksmitowane z powodu zmiany w bazie danych; lub punkt przerwania nie zostanie trafiony, co oznacza, że SqlCacheDependencies.aspx
teraz pokazuje nieaktualne dane. Jeśli punkt przerwania nie zostanie trafiony, prawdopodobnie usługa sondowania nie została jeszcze wyzwolona od czasu zmiany danych. Pamiętaj, że usługa sondowania sprawdza zmiany Products
w tabeli co pollTime
milisekundy, dlatego występuje opóźnienie między aktualizacją danych bazowych a eksmitowaniem danych buforowanych.
Uwaga
To opóźnienie jest bardziej prawdopodobne podczas edytowania jednego z produktów za pośrednictwem kontrolki GridView w programie SqlCacheDependencies.aspx
. W samouczku Buforowanie danych w architekturze dodaliśmy MasterCacheKeyArray
zależność pamięci podręcznej, aby upewnić się, że dane edytowane za pomocą ProductsCL
metody klasy zostały UpdateProduct
wykluczone z pamięci podręcznej. Jednak zastąpiliśmy tę zależność pamięci podręcznej podczas modyfikowania AddCacheItem
metody wcześniej w tym kroku i dlatego ProductsCL
klasa będzie nadal pokazywać buforowane dane, dopóki system sondowania nie zanotuje zmiany w Products
tabeli. Zobaczymy, jak ponownie wprowadzić zależność pamięci podręcznej MasterCacheKeyArray
w kroku 7.
Krok 7. Kojarzenie wielu zależności z buforowanym elementem
Pamiętaj, że MasterCacheKeyArray
zależność pamięci podręcznej jest używana do zapewnienia, że wszystkie dane związane z produktem są eksmitowane z pamięci podręcznej po zaktualizowaniu dowolnego elementu skojarzonego z nim. Na przykład GetProductsByCategoryID(categoryID)
metoda buforuje ProductsDataTables
wystąpienia dla każdej unikatowej wartości categoryID . Jeśli jeden z tych obiektów zostanie wykluczony, MasterCacheKeyArray
zależność pamięci podręcznej gwarantuje, że pozostałe zostaną również usunięte. Bez tej zależności pamięci podręcznej, gdy buforowane dane są modyfikowane, istnieje możliwość, że inne buforowane dane produktu mogą być nieaktualne. W związku z tym ważne jest, aby zachować MasterCacheKeyArray
zależność pamięci podręcznej podczas korzystania z zależności pamięci podręcznej SQL. Jednak metoda pamięci podręcznej Insert
danych zezwala tylko na pojedynczy obiekt zależności.
Ponadto podczas pracy z zależnościami pamięci podręcznej SQL może być konieczne skojarzenie wielu tabel bazy danych jako zależności. Na przykład ProductsDataTable
buforowany w ProductsCL
klasie zawiera kategorię i nazwy dostawców dla każdego produktu, ale AddCacheItem
metoda używa tylko zależności od Products
klasy . W takiej sytuacji, jeśli użytkownik zaktualizuje nazwę kategorii lub dostawcy, buforowane dane produktu pozostaną w pamięci podręcznej i będą nieaktualne. W związku z tym chcemy, aby buforowane dane produktu zależały nie tylko Products
od tabeli, ale także w Categories
tabelach i Suppliers
.
KlasaAggregateCacheDependency
zapewnia metodę kojarzenia wielu zależności z elementem pamięci podręcznej. Zacznij od utworzenia AggregateCacheDependency
wystąpienia. Następnie dodaj zestaw zależności przy użyciu AggregateCacheDependency
metody s Add
. Podczas wstawiania elementu do pamięci podręcznej danych następnie przekaż w wystąpieniu AggregateCacheDependency
. Gdy dowolnaAggregateCacheDependency
z zależności wystąpienia ulegnie zmianie, buforowany element zostanie wykluczony.
Poniżej przedstawiono zaktualizowany kod dla ProductsCL
metody klasy s AddCacheItem
. Metoda tworzy zależność pamięci podręcznej MasterCacheKeyArray
wraz z obiektami SqlCacheDependency
dla Products
tabel , Categories
i Suppliers
. Wszystkie te elementy są łączone w jeden AggregateCacheDependency
obiekt o nazwie aggregateDependencies
, który jest następnie przekazywany do Insert
metody .
Private Sub AddCacheItem(ByVal rawKey As String, ByVal value As Object)
Dim DataCache As System.Web.Caching.Cache = HttpRuntime.Cache
' Make sure MasterCacheKeyArray(0) is in the cache - if not, add it.
If DataCache(MasterCacheKeyArray(0)) Is Nothing Then
DataCache(MasterCacheKeyArray(0)) = DateTime.Now
End If
'Create the CacheDependency
Dim masterCacheKeyDependency As _
New Caching.CacheDependency(Nothing, MasterCacheKeyArray)
' Add the SqlCacheDependency objects for Products, Categories, and Suppliers
Dim productsTableDependency As _
New Caching.SqlCacheDependency("NorthwindDB", "Products")
Dim categoriesTableDependency As _
New Caching.SqlCacheDependency("NorthwindDB", "Categories")
Dim suppliersTableDependency As _
New Caching.SqlCacheDependency("NorthwindDB", "Suppliers")
' Create an AggregateCacheDependency
Dim aggregateDependencies As New Caching.AggregateCacheDependency()
aggregateDependencies.Add(masterCacheKeyDependency, productsTableDependency, _
categoriesTableDependency, suppliersTableDependency)
DataCache.Insert(GetCacheKey(rawKey), value, aggregateDependencies, _
Caching.Cache.NoAbsoluteExpiration, Caching.Cache.NoSlidingExpiration)
End Sub
Przetestuj ten nowy kod. Teraz zmiany w Products
tabelach , Categories
lub Suppliers
powodują eksmitowanie buforowanych danych. Co więcej, ProductsCL
metoda klasy s UpdateProduct
, która jest wywoływana podczas edytowania produktu za pośrednictwem gridview, eksmituje MasterCacheKeyArray
zależność pamięci podręcznej, co powoduje eksmitowanie buforowanej ProductsDataTable
pamięci podręcznej, a dane mają zostać ponownie pobrane w następnym żądaniu.
Uwaga
Zależności pamięci podręcznej SQL mogą być również używane z buforowaniem danych wyjściowych. Aby zapoznać się z pokazem tej funkcji, zobacz: Using ASP.NET Output Caching with SQL Server (Używanie buforowania danych wyjściowych ASP.NET z SQL Server).
Podsumowanie
Podczas buforowania danych bazy danych dane w idealnym przypadku pozostaną w pamięci podręcznej, dopóki nie zostaną zmodyfikowane w bazie danych. Dzięki ASP.NET 2.0 można tworzyć zależności pamięci podręcznej SQL i używać ich zarówno w scenariuszach deklaratywnych, jak i programowych. Jednym z wyzwań związanych z tym podejściem jest odkrycie, kiedy dane zostały zmodyfikowane. Pełne wersje platformy Microsoft SQL Server 2005 zapewniają możliwości powiadomień, które mogą powiadamiać aplikację o zmianie wyniku zapytania. W przypadku wersji Express Edition SQL Server 2005 i starszych wersji SQL Server należy zamiast tego użyć systemu sondowania. Na szczęście skonfigurowanie niezbędnej infrastruktury sondowania jest dość proste.
Szczęśliwe programowanie!
Dalsze informacje
Aby uzyskać więcej informacji na temat tematów omówionych w tym samouczku, zapoznaj się z następującymi zasobami:
- Używanie powiadomień zapytań w programie Microsoft SQL Server 2005
- Tworzenie powiadomienia zapytania
- Buforowanie w ASP.NET za pomocą
SqlCacheDependency
klasy - narzędzie rejestracji ASP.NET SQL Server (
aspnet_regsql.exe
) - Omówienie
SqlCacheDependency
Informacje o autorze
Scott Mitchell, autor siedmiu książek ASP/ASP.NET i założyciel 4GuysFromRolla.com, współpracuje z technologiami internetowymi firmy Microsoft od 1998 roku. Scott pracuje jako niezależny konsultant, trener i pisarz. Jego najnowsza książka to Sams Teach Yourself ASP.NET 2.0 w ciągu 24 godzin. Można do niego dotrzeć pod adresem mitchell@4GuysFromRolla.com. Lub za pośrednictwem swojego bloga, który można znaleźć na stronie http://ScottOnWriting.NET.
Specjalne podziękowania
Ta seria samouczków została przejrzyona przez wielu przydatnych recenzentów. Głównymi recenzentami tego samouczka byli Marko Rangel, Teresa Murphy i Hilton Giesenow. Chcesz przejrzeć nadchodzące artykuły MSDN? Jeśli tak, upuść mi wiersz pod adresemmitchell@4GuysFromRolla.com .