Декларативное кэширование данных в ASP.NET

Элементы управления источником данных ASP.NET 2.0 предоставляют простой декларативный подход к осуществлению доступа и изменению данных. Просто настройте пару свойств элемента управления источником данных, свяжите их с элементом управления данными и готово - данные будут получены и отображены, при этом вам не надо будет писать и строки кода!

В дополнение к декларативному способу работы с данными, элемент управления источником данных также может декларативно кэшировать информацию. Кэширование является часто используемой техникой в приложениях, управляемых данными, для повышения производительности. Техника заключается в хранении информации в памяти базы данных, где доступ к ней может быть с легкостью осуществлен. ASP.NET предоставляет кэширование данных, что является программно-доступным кэшем, часто используемым для хранения результатов базы данных.

Стоит отметить также, что элементы управления источником данных предоставляют декларативный доступ к кэшу данных. Простой установкой новых свойств элементы управления источником данных будут хранить полученную информацию в кэше данных. В следующий раз, когда данные будут запрошены, элементы управления получат информацию из кэша, вместо того, чтобы запрашивать ее из базы данных. В данной статье мы рассмотрим такой способ настройки элемента управления источником данных, который поможет хранить  информацию в кэше  данных. Читайте далее, чтобы узнать больше об этом!

Знакомство с кэшированием

Кэширование - это техника, разработанная для улучшения производительности путем переноса информации из более ресурсоемких хранилищ в менее требовательные. Хранилище - это место, где хранятся данные - к примеру, база данных, файл, память и т.д. Каноническим примером кэширования  является получение информации из базы данных и хранение ее в памяти приложения, поскольку приложение сможет считывать информацию из своей памяти в несколько раз быстрее, чем в случае, когда она находится на удаленном сервере баз данных.

Существуют также некоторые ограничения. Почти всегда более эффективные хранилища данных имеют меньший объем по сравнению с более медленными хранилищами. То есть база данных хранит больше информации, чем может поместиться в памяти приложения, тем самым не вся информация может быть кэширована. Более того, при добавлении информации в кэш, наверняка придется удалить другую кэшированную информацию для того, чтобы освободить немного места.

Также кэширование предполагает отключение соединения между данными в приложении и источником данных. Если дата из источника обновляется либо удаляется, то приложение, работающее с копией в кэше, не будет знать о том, что данные обновлены, до следующего момента, когда оно обратится к источнику данных. В этих целях информация обычно кэшируется на определенный промежуток времени, после чего информация автоматически удаляется. Это ставит ограничение на период кэширования данных. (ASP.NET 2.0 предлагает зависимости кэша SQL, что является более практической техникой для определения устарелости данных.)

Кэш данных является наиболее часто используемым хранилищем информации в приложениях ASP.NET. Это кэш, хранящийся в памяти и доступный через объект Cache. Чтобы добавить новый элемент в кэш, вам понадобится указать ключ для него (где ключом является строка). Аналогично для того, чтобы получить элемент из кэша, вам понадобится сослаться на него, используя ключ. Следующий блок кода демонстрирует чтение и запись в кэше данных:

// C#
Cache["key"] = ObjectToCache;  // запись в кэш
object myData = Cache["key"];  // чтение из кэша

' VB
Cache("key") = ObjectToCache         ' запись в кэш
Dim myData As Object = Cache("key")  ' чтение из кэша

Кэширование данных, полученных из элементов управления источником данных

Элементы управления ObjectDataSource, SqlDataSource, AccessDataSource и XmlDataSource содержат свойства, которые указывают элементам управления источником данных, что необходимо кэшировать информацию в кэше данных. Данное кэширование выполняется автоматически и не требует написания кода. Ключевыми свойствами являются:

  • EnableCaching - значение типа Boolean, от которого зависит, будет произведено кэширование или нет. По умолчанию оно установлено в False. Вам понадобится установить данное значение в True, чтобы элемент управления источником данных выполнял кэширование.
  • CacheDuration - значение типа Integer, которое указывает длительность кэширования информации (в секундах).
  • CacheExpirationPolicy - указывает тип окончания кэширования - может быть установлен в Absolute (абсолютное) либо Sliding (плавное). Абсолютное означает то, что элемент кэша будет удален через определенное в CacheDuration время с момента его записи в кэше. Плавный тип подразумевает удаление из кэша через время, указанное в CacheDuration с момента последнего доступа к данным. По умолчанию установлено в Absolute.
  • CacheKeyDependency - значение типа String, которое указывает на дополнительный элемент в кэше, служащий в качестве отношения. Если указано данное значение, то когда изменяется кэшированный элемент в CacheKeyDependency, источник данных также изменит информацию в кэше.

Элементы управления SqlDataSource и ObjectDataSource также имеют свойство SqlCacheDependency, которое должно быть применено в случае, когда используется зависимость SQL-кэша. Также стоит отметить, что хотя AccessDataSource обладает таким свойством, попытка его использования в результате вызовет исключение NotSupportedException. Также стоит заметить, что элементы источника данных будут кэшировать данные только в случае, когда EnableCaching установлено в True, либо когда истечет время, указанное в свойстве CacheDuration, либо когда указана зависимость SQL-кэша.

Следующий декларативный синтаксис демонстрирует AccessDataSource, который настроен для абсолютного кэширования на 30-секундный период (также изучите примеры, приведенные в конце данной статьи:

<asp:AccessDataSource ID="ProductsDataSource" runat="server" 
    DataFile="~/App_Data/Northwind.mdb"
    SelectCommand="SELECT * FROM [Products]"
    CacheDuration="30"
    EnableCaching="True">
</asp:AccessDataSource>

Когда метод Select данного элемента AccessDataSource вызывается другим элементом управления (таким как GridView), AccessDataSource сначала проверит наличие информации в кэше. Если ее там не будет, то он подсоединится к базе данных Microsoft Access (Northwind.mdb) и запустит запрос SelectCommand. Вследствие  этого он кэширует результаты в кэше данных и возвращает информацию в запрашивающий элемент управления данными. Теперь представьте, что 5-ю секундами позже другой пользователь посещает страницу. Элемент управления данными опять запросит данные из AccessDataSource, но на этот раз информация будет в кэше. Тем самым AccessDataSource возвратит информацию в элемент управления данными, не осуществляя соединения к базе данных. Тем не менее, через 30 секунд  информация будет удалена из кэша, и последующий запрос будет опять осуществлять соединение с базой данных.

Детальное изучение кэширования данных элементом управления источником данных

Когда вызывается метод Select для элемента управления данными, который был настроен на кэширование, элемент управления источником данных начинает с проверки того, находится ли  информация в кэше. Как уже упоминалось ранее, доступ к кэшированным элементам осуществляется посредством строкового ключа. Ключ, используемый элементом управления источником данных, является комбинацией необходимых свойств. Для SqlDataSource используются значения свойств CacheDuration, CacheExpirationPolicy, ConnectionString, SelectCommand и SelectParameters. Это обеспечит уникальность кэша для соединения, для SELECT-запроса и для названий и значений параметров запроса (если таковые есть).

Если элемент был найден в кэше данных, то элемент управления источником данных возвратит кэшированную информацию и не вызовет событие Selecting. Событие Selecting запускается каждый раз, когда вызывается метод Select элемента управления источника данных и данные передаются из хранилища.

Если же элемент не был найден в кэше, то тогда элемент управления источником продолжит нормальный процесс выборки: вызывается событие Selecting, осуществляется доступ к нижележащему хранилищу данных и информация возвращается, а затем вызывается метод Selected. До того как информация будет получена, элемент управления источником сначала добавит ее в кэш, используя тот же принцип создания ключа, который мы обсуждали раньше.

Следующая диаграмма демонстрирует процесс кэширования для ObjectDataSource, хотя процесс такой же, что и для элементов управления AccessDataSource, SqlDataSource, XmlDataSource. Заметьте, что событие Selecting не вызывается в случае, если элемент был получен из кэша.


Мы можем воспользоваться тем фактом, что событие Selecting вызывается только в случае, если данные передаются из хранилища данных для отображения их на странице когда данные были скэшированы. Примеры, доступные в конце данной статьи используют элемент управления Label, который обновляется значениями текущих даты и времени каждый раз, когда вызывается событие Selecting, тем самым отображая время последнего обновления кэша. Хотя пользователю не интересна данная информация, она является пригодной для разработчиков так как показывает время, когда кэшированная информация сохраняется и какие действия вызывают преждевременное удаление информации.

Удаление элементов из кэша

Одним из недостатков кэширования информации является старение данных. Кроме удаления кэшированной информации по истечению какого-либо срока, существуют другие способы удаления. Элементы управления источником данных автоматически высвобождают данные из кэша, если вызывается метод Insert, Update или Delete элемента управления источником данных. Вкратце, методы элемента управления источником данных изменяют хранилище данных, как об этом свидетельствуют их имена, и также могут быть декларативно настроены. Когда выполняется какой-либо из этих методов, элемент управления источником данных изменяет хранилище данных,  таким образом  благоразумно удаляя кэшированную информацию,  поскольку известно, что она уже не является настолько новой. Вы можете увидеть такое поведение в примерах, включенных в приложение к статье.

Вы также можете программно удалить кэшированную информацию элемента управления источником данных используя свойство CacheKeyDependency. Просто установите свойство CacheKeyDependency в значение ключа какой-либо информации в кэше. Далее, чтобы удалить данные из кэша элемента просто обновите CacheKeyDependency элемента кэша .

Начните с установки свойства CacheKeyDependency элемента управления источником данных в название ключа, который служит в качестве указателя зависимости. Вы можете выбрать старое название для данного свойства:

<asp:AccessDataSource ID="ProductsDataSource" runat="server" 
    DataFile="~/App_Data/Northwind.mdb"
    SelectCommand="SELECT * FROM [Products]"
    CacheDuration="30"
    EnableCaching="True"
    CacheKeyDependency="ProductsDependency">
</asp:AccessDataSource>

Далее, данный элемент обязательно должен существовать в кэше, в противном случае информация, кэшированная элементом управления источником данных будет сразу же удалена из кэша при добавлении. В обработчике события Page_Load проверьте существует ли данный элемент, и добавьте его если его там нет:

Protected Sub Page_Load(ByVal sender As Object, ByVal e As EventArgs) Handles Me.Load
    'Добавление элемента Cache при необходимости
    If Cache(ProductsDataSource.CacheKeyDependency) Is Nothing Then
        Cache(ProductsDataSource.CacheKeyDependency) = DateTime.Now
    End If
End Sub

Здесь я присваиваю DateTime.Now в элемент кэша, но вы можете использовать любое значение. DateTime.Now подходит, так как указывает на время последнего обновления.

Для того чтобы удалить кэшированную информацию программным путем, просто обновите значение элемента кэша Cache(ProductsDataSource.CacheKeyDependency), к примеру в текущую дату и время (Cache(ProductsDataSource.CacheKeyDependency) = DateTime.Now). В приложении к данной статье существует пример, включающий в себя кнопку (элемент управления Button), при нажатии которой информация удаляется из кэша путем обновления Cache(ProductsDataSource.CacheKeyDependency) в текущую дату и время. И это все!

Вывод

Осуществление доступа и работа с информацией не так сложны благодаря элементам управления источником данных - от вас даже не требуется написание кода. Как мы уже увидели в данной статье, декларативная модель также расширена для поддержки кэширования. Информация элемента управления источником данных может быть кэширована в кэше данных, при этом можно использовать ограничения по времени путем настройки свойства EnableCaching в True и свойства CacheDuration в значение периода, по истечении которого необходимо удалить данные (секунды). Элементы управления SqlDataSource и ObjectDataSource также могут использовать зависимость кэша SQL, но об этом мы поговорим в следующих статьях.

Scott Mitchell

Скачать исходники примеров