Простая SqlCacheDependency - PullRequest
       21

Простая SqlCacheDependency

5 голосов
/ 27 июня 2019

Кажется, что почти каждый прочитанный мной учебник неправильно настроен SqlCacheDependency . Я полагаю, что они обычно смешивают устаревший метод опроса с методом уведомления о запросе.

Вот два из множества примеров:


На основании моего тестирования, если вы используете брокера (MSSQL 2015+), вам не нужно вносить какие-либо .config изменения, а также не нужно делать какие-либо вызовы SqlCacheDependencyAdmin (не нужно определять таблицы и т. Д.) ).

Я упрощаю, просто сделай это ...

SqlDependency.Start(connString)
...
queryString = "SELECT ...";
cacheName = "SqlCache" + queryString.GetHashCode();
...
using (var connection = new SqlConnection(connString))
{
    connection.Open();
    var cmd = new SqlCommand(queryString, connection)
    {
        Notification = null, 
        NotificationAutoEnlist = true
    };

    var dependency = new SqlCacheDependency(cmd);

    SqlDataReader reader = cmd.ExecuteReader();
    try
    {
        while (reader.Read())
        {
            // Set the result you want to cache
            data = ...
        }
    }
    finally
    {
        reader.Close();
    }

    HostingEnvironment.Cache.Insert(cacheName, data, dependency);
}

(Код, который проверяет, является ли кеш нулевым или нет, не включен, так как это всего лишь настройка. Я просто хочу показать настройки кеша)

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

Более удивительным для меня является то, что правила составления запроса имеют уведомление:

Для теста мне нужно 1000 раз выполнить запрос к таблице с именем «Настройки». Затем я обновляю значение в таблице и повторяю запрос.

Я наблюдаю за профилировщиком любых запросов, включающих слово «Настройки», и вижу, что запрос выполняется только 1 раз (для установки кэша), а затем выполняется оператор обновления, а затем запрос повторяется еще раз (кеш был признан недействительным, и запрос снова запустился)

Я беспокоюсь, что за 2-3 часа борьбы с правильным способом сделать это я что-то упускаю, и действительно ли это так просто?

Могу ли я просто поставить любой запрос, и он будет работать? Я ищу любые указатели, где я делаю что-то опасное / нестандартное, или мелкий шрифт, который мне не хватает

Ответы [ 2 ]

2 голосов
/ 03 июля 2019

переменная зависимость = новая SqlCacheDependency (cmd); когда вы пишете такой запрос, вы автоматически определяете имя таблицы в нем. Ваше соединение уже имеет имя БД. Это не явный способ сделать то же самое.

Явный способ отловить исключение и узнать, что пошло не так.

// Declare the SqlCacheDependency instance, SqlDep. 
        SqlCacheDependency SqlDep = null; 

        // Check the Cache for the SqlSource key. 
        // If it isn't there, create it with a dependency 
        // on a SQL Server table using the SqlCacheDependency class. 
        if (Cache["SqlSource"] == null) { 

            // Because of possible exceptions thrown when this 
            // code runs, use Try...Catch...Finally syntax. 
            try { 
                // Instantiate SqlDep using the SqlCacheDependency constructor. 
                SqlDep = new SqlCacheDependency("Northwind", "Categories"); 
            } 

            // Handle the DatabaseNotEnabledForNotificationException with 
            // a call to the SqlCacheDependencyAdmin.EnableNotifications method. 
            catch (DatabaseNotEnabledForNotificationException exDBDis) { 
                try { 
                    SqlCacheDependencyAdmin.EnableNotifications("Northwind"); 
                } 

                // If the database does not have permissions set for creating tables, 
                // the UnauthorizedAccessException is thrown. Handle it by redirecting 
                // to an error page. 
                catch (UnauthorizedAccessException exPerm) { 
                    Response.Redirect(".\\ErrorPage.htm"); 
                } 
            } 

            // Handle the TableNotEnabledForNotificationException with 
            // a call to the SqlCacheDependencyAdmin.EnableTableForNotifications method. 
            catch (TableNotEnabledForNotificationException exTabDis) { 
                try { 
                    SqlCacheDependencyAdmin.EnableTableForNotifications("Northwind", "Categories"); 
                } 

                // If a SqlException is thrown, redirect to an error page. 
                catch (SqlException exc) { 
                    Response.Redirect(".\\ErrorPage.htm"); 
                } 
            } 

            // If all the other code is successful, add MySource to the Cache 
            // with a dependency on SqlDep. If the Categories table changes, 
            // MySource will be removed from the Cache. Then generate a message 
            // that the data is newly created and added to the cache. 
            finally { 
                Cache.Insert("SqlSource", Source1, SqlDep); 
                CacheMsg.Text = "The data object was created explicitly."; 

            } 
        } 

        else { 
            CacheMsg.Text = "The data was retrieved from the Cache."; 
        }
0 голосов
/ 05 июля 2019

Как указано в https://docs.microsoft.com/en-us/dotnet/api/system.web.caching.sqlcachedependency?view=netframework-4.8 «Использование объекта SqlCacheDependency с уведомлением о запросе SQL Server 2005 не требует явной настройки.»

Итак, в CMD есть явные имена таблиц, и ADO.net выдает правильные команды конфигурации компонента Service Broker. Когда таблица обновляется, SQL Server отправляет сообщение компонента Service Broker о том, что таблица была обновлена. Когда ADO.net проверяет CMD, он проверяет явные таблицы в посреднике на наличие обновлений.

Вот почему CMD, связанный с SQlCacheDependency, должен использовать явные таблицы.

...