учебник. использование устойчивости к подключению и перехват команд с помощью Entity Framework в приложении ASP.NET MVC
пока приложение запущено локально в IIS Express на компьютере разработчика. Чтобы сделать приложение доступным для других пользователей через Интернет, необходимо развернуть его на веб-сайте поставщика услуг размещения и развернуть базу данных на сервере базы данных.
В этом учебнике вы узнаете, как использовать устойчивость подключений и перехват команд. они являются двумя важными функциями Entity Framework 6, которые особенно полезны при развертывании в облачной среде: устойчивость подключений (автоматические повторы для временных ошибок) и перехват команд (перехват всех запросов SQL, отправленных в базу данных, для их записи в журнал или изменения).
Это необязательное руководство по устойчивости к подключению и перехвату команд. Если пропустить этот учебник, в последующих руководствах потребуется внести несколько незначительных изменений.
В этом учебнике рассмотрены следующие задачи.
- Включить устойчивость подключений
- Включить перехват команд
- Тестирование новой конфигурации
Предварительные требования
Включить устойчивость подключений
при развертывании приложения в Windows Azure вы развернете базу данных на Windows База данных SQL Azure облачной службе базы данных. Ошибки временного подключения обычно чаще возникают при подключении к облачной службе базы данных, чем когда веб-сервер и сервер базы данных напрямую соединяются друг с другом в одном центре обработки данных. Даже если облачный веб-сервер и облачная служба базы данных размещаются в одном центре обработки данных, между ними есть больше сетевых подключений, которые могут иметь проблемы, такие как подсистемы балансировки нагрузки.
Кроме того, облачная служба обычно совместно используется другими пользователями. Это означает, что их скорость реагирования может быть затронута. А доступ к базе данных может регулироваться. Регулирование означает, что служба базы данных создает исключения при попытке доступа к ней чаще, чем разрешено в Соглашение об уровне обслуживания (SLA).
Многие или большинство проблем с подключением при доступе к облачной службе являются временными, то есть они разрешаются в течение короткого периода времени. Поэтому при попытке выполнить операцию базы данных и получить тип ошибки, которая обычно является временной, можно повторить операцию после короткого ожидания, и операция может быть выполнена успешно. Вы можете предоставить пользователям гораздо больше возможностей, если вы обрабатываете временные ошибки, автоматически повторяя попытку, делая большинство из них невидимыми для клиента. функция устойчивости подключений в Entity Framework 6 автоматизирует процесс повторного выполнения неудачных SQLных запросов.
Для конкретной службы базы данных необходимо соответствующим образом настроить функцию устойчивости подключений.
- Он должен определять, какие исключения, вероятно, будут временными. Необходимо повторить ошибки, вызванные временной потерей подключения к сети, а не ошибки, вызванные ошибками в программе, например.
- Время между повторными попытками неудачной операции должно дожидаться соответствующего времени. Можно подождать больше времени между попытками пакетной обработки, чем веб-страница в Интернете, где пользователь ожидает ответа.
- Необходимо повторить необходимое количество раз, прежде чем оно будет выдаваться. Может потребоваться повторить попытку в пакетном процессе, который будет находиться в интерактивном приложении.
эти параметры можно настроить вручную для любой среды базы данных, поддерживаемой поставщиком Entity Framework, но значения по умолчанию, которые обычно подходят для интерактивного приложения, использующего Windows База данных SQL Azure, уже настроены, и эти параметры будут реализованы для приложения университета Contoso.
чтобы включить устойчивость к подключению, достаточно создать класс в сборке, производной от класса DbConfiguration , а в этом классе задать стратегию выполненияБаза данных SQL, которая в EF является еще одним термином для политики повтора.
В папке DAL добавьте файл класса с именем счулконфигуратион. CS.
Замените код шаблона следующим кодом:
Entity Framework автоматически выполняет код, найденный в классе, производном от DbConfiguration . Класс можно использовать DbConfiguration для задания конфигурации в коде, который в противном случае можно было бы сделать в файле Web.config . Дополнительные сведения см. в разделе EntityFramework Code-Based Configuration.
В студентконтроллер. CSдобавьте using инструкцию для System.Data.Entity.Infrastructure .
Измените все catch блоки, которые перехватывают DataException исключения, чтобы они перехватывать RetryLimitExceededException исключения. Например:
Вы использовали DataException для выяснения ошибок, которые могут быть временными, чтобы дать понятное сообщение "повторить попытку". Но теперь, когда вы включили политику повтора, единственные ошибки, скорее всего, будут уже выполнены и завершились неудачно, а реальное исключение будет заключено в RetryLimitExceededException оболочку исключения.
Включить перехват команд
Теперь, когда вы включили политику повтора, как проверить, работает ли она должным образом? Не так просто принудительно выполнять временную ошибку, особенно если вы работаете локально, и вам было бы очень сложно интегрировать фактические временные ошибки в автоматизированный модульный тест. чтобы протестировать функцию устойчивости подключений, необходим способ перехвата запросов, которые Entity Framework отправляется в SQL Server, и замены SQL Server ответа на тип исключения, который обычно является временным.
Можно также использовать перехват запросов, чтобы реализовать оптимальную методику для облачных приложений: регистрировать задержку и успех или неудачу всех вызовов внешних служб , таких как службы баз данных. EF6 предоставляет специальный API для ведения журнала , который упрощает ведение журнала, но в этом разделе учебника вы узнаете, как использовать функцию перехвата Entity Framework напрямую, как для ведения журнала, так и для моделирования временных ошибок.
Создание интерфейса и класса ведения журналаДля ведения журнала рекомендуется использовать интерфейс, а не вызовы с жестким кодированием к классу System. Diagnostics. Trace или журналу. Это упрощает изменение механизма ведения журнала в дальнейшем, если вам когда-либо потребуется это сделать. Итак, в этом разделе вы создадите интерфейс ведения журнала и класс для его реализации./p>
Создайте папку в проекте и назовите ее Logging.
В папке Logging создайте файл класса с именем ILogger. CSи замените код шаблона следующим кодом:
Интерфейс предоставляет три уровня трассировки для указания относительной важности журналов, и один предназначен для предоставления сведений о задержке для вызовов внешних служб, таких как запросы к базе данных. Методы ведения журнала имеют перегрузки, которые позволяют передавать исключение. Это значит, что сведения об исключении, включая трассировку стека и внутренние исключения, надежно регистрируются классом, реализующим интерфейс, вместо того, чтобы полагаться на него в каждом вызове метода ведения журнала в рамках всего приложения.
методы трацеапи позволяют контролировать задержку каждого вызова к внешней службе, например База данных SQL.
В папке Logging создайте файл класса с именем Logger. CSи замените код шаблона следующим кодом:
Для трассировки в реализации используется System. Diagnostics. Это встроенная функция .NET, которая позволяет легко создавать и использовать сведения трассировки. Существует много прослушивателей, которые можно использовать с трассировкой System. Diagnostics для записи журналов в файлы, например, или для записи их в хранилище BLOB-объектов в Azure. Ознакомьтесь с некоторыми вариантами и ссылками на другие ресурсы, чтобы получить дополнительные сведения об устранении неполадок веб-сайтов Azure в Visual Studio. в этом учебнике будут рассмотрены только журналы в окне вывода Visual Studio.
В рабочем приложении можно рассматривать пакеты трассировки, отличные от System. Diagnostics, а интерфейс ILogger позволяет относительно легко переключиться на другой механизм трассировки, если вы решили это сделать.
Создание классов перехватчиковДалее предстоит создать классы, которые будут вызываться Entity Framework каждый раз, когда будет отправлен запрос в базу данных, один из которых имитирует временные ошибки и один для ведения журнала. Эти классы перехватчиков должны быть производными от DbCommandInterceptor класса. В них написаны переопределения методов, которые автоматически вызываются при выполнении запроса. В этих методах можно проверить или зарегистрировать запрос, отправляемый в базу данных, а также изменить запрос перед его отправкой в базу данных или вернуть что-либо в Entity Framework, не передавая запрос в базу данных.
чтобы создать класс перехватчика, который будет регистрировать каждый SQL запрос, отправленный в базу данных, создайте файл класса с именем счулинтерцепторлоггинг. cs в папке DAL и замените код шаблона следующим кодом:
Для успешных запросов или команд этот код записывает журнал сведений со сведениями о задержке. Для исключений создается журнал ошибок.
Чтобы создать класс перехватчика, который будет формировать фиктивные временные ошибки при вводе в поле поиска "Throw", создайте файл класса с именем счулинтерцептортрансиентеррорс. CS в папке DAL и замените код шаблона следующим кодом:
Этот код переопределяет ReaderExecuting только метод, который вызывается для запросов, которые могут возвращать несколько строк данных. Если вы хотите проверить устойчивость подключения для других типов запросов, можно также переопределить NonQueryExecuting методы и ScalarExecuting , как это делает перехватчик ведения журнала.
при запуске страницы Student и вводе в качестве строки поиска "Throw" этот код создает фиктивный База данных SQL исключение с номером 20, обычно тип является временным. другие номера ошибок, которые в настоящее время считаются временными, — 64, 233, 10053, 10054, 10060, 10928, 10929, 40197, 40501 и 40613, но они могут быть изменены в новых версиях База данных SQL.
Код возвращает исключение, Entity Framework вместо выполнения запроса и передачи результатов запроса. Временное исключение возвращается четыре раза, а затем код возвращается к нормальной процедуре передачи запроса в базу данных.
Так как все заносится в журнал, вы сможете увидеть, что Entity Framework пытается выполнить запрос четыре раза, прежде чем он будет завершен, и единственное различие в приложении заключается в том, что для отображения страницы с результатами запроса требуется больше времени.
Количество повторных попыток, которое Entity Framework будет доступно для настройки; код указывает четыре раза, так как это значение по умолчанию для политики выполнения База данных SQL. При изменении политики выполнения также изменяется код, указывающий, сколько раз создаются временные ошибки. Кроме того, можно изменить код, чтобы создать дополнительные исключения, чтобы Entity Framework выдаст RetryLimitExceededException исключение.
Значение, введенное в поле поиска, будет находиться в command.Parameters[0] и command.Parameters[1] (одно имя используется для имени, а другое для фамилии). При обнаружении значения "% Throw%" в этих параметрах "a" заменяется "Throw", чтобы некоторые учащиеся были найдены и возвращались.
Это просто удобный способ проверки устойчивости подключения на основе изменения некоторых входных данных в пользовательском интерфейсе приложения. Можно также написать код, который создает временные ошибки для всех запросов или обновлений, как описано далее в комментариях к методу дбинтерцептион. Add .
В Global. asaxдобавьте следующие using инструкции:
Добавьте выделенные строки в Application_Start метод:
Эти строки кода приводят к тому, что код перехватчика будет выполняться, когда Entity Framework отправляет запросы в базу данных. Обратите внимание, что, поскольку вы создали отдельные классы перехватчиков для моделирования временных ошибок и ведения журнала, вы можете независимо включать и отключать их.
Перехватчики можно добавлять с помощью DbInterception.Add метода в любом месте кода; он не должен находиться в Application_Start методе. Другой вариант — разместить этот код в классе DbConfiguration, созданном ранее, чтобы настроить политику выполнения.
При помещении этого кода следует избегать выполнения DbInterception.Add одного и того же перехватчика более одного раза или получить дополнительные экземпляры перехватчиков. например, если вы добавите перехватчик событий дважды, вы увидите два журнала для каждого SQL запроса.
Перехватчики выполняются в порядке регистрации (порядок, в котором DbInterception.Add вызывается метод). Порядок может быть важен в зависимости от того, что вы делаете в перехватчике. например, перехватчик может изменить SQL команду, которую он получает в CommandText свойстве. при изменении команды SQL следующий перехватчик получит команду changed SQL, а не исходную команду SQL.
Вы написали код моделирования временной ошибки таким образом, который позволяет вызывать временные ошибки, вводя другое значение в пользовательском интерфейсе. В качестве альтернативы можно написать код перехватчика, чтобы всегда создавать последовательность временных исключений без проверки конкретного значения параметра. Затем можно добавить перехватчик, только если нужно создать временные ошибки. Однако при этом не добавляйте перехватчик до завершения инициализации базы данных. Иными словами, перед созданием временных ошибок выполните по крайней мере одну операцию с базой данных, например запрос к одному из наборов сущностей. Entity Framework выполняет несколько запросов во время инициализации базы данных и не выполняется в транзакции, поэтому ошибки во время инициализации могут привести к несогласованному состоянию контекста.
Тестирование новой конфигурации
Нажмите клавишу F5 , чтобы запустить приложение в режиме отладки, а затем перейдите на вкладку students (учащиеся ).
просмотрите окно вывода Visual Studio, чтобы просмотреть выходные данные трассировки. Возможно, придется прокрутить последние ошибки JavaScript, чтобы перейти к журналам, записанным вашим средством ведения журнала.
обратите внимание, что можно просмотреть фактические SQL запросы, отправляемые в базу данных. Вы увидите некоторые начальные запросы и команды, которые Entity Framework начать работу, проверив таблицу журнала версии и миграции базы данных (вы узнаете о миграции в следующем руководстве). Отобразится запрос на разбиение на страницы, чтобы узнать, сколько учащихся, и, наконец, вы видите запрос, получит данные учащегося.
На странице учащихся введите "Throw" в качестве строки поиска и нажмите кнопку " Поиск".
Вы заметите, что браузер перестает отвечать на несколько секунд, а Entity Framework повторяет запрос несколько раз. Первая повторная попытка выполняется очень быстро, а затем ждет до тех пор, пока не будет увеличена каждая дополнительная попытка. Этот процесс ожидания перед каждой повторной попыткой называется экспоненциальнойзадержкой.
Когда отобразится страница, отображающая учащихся, у которых в своих именах есть «an», просмотрите окно вывод, и вы увидите, что один и тот же запрос попытался пять раз, первые четыре раза возвращают временные исключения. Для каждой временной ошибки вы увидите журнал, который вы пишете при создании временной ошибки в SchoolInterceptorTransientErrors классе ("возвращение временной ошибки для команды. "), и при получении SchoolInterceptorLogging исключения вы увидите запись журнала.
Так как вы указали строку поиска, запрос, возвращающий данные учащегося, является параметризованным:
Вы не записываете значения параметров, но это можно сделать. Если вы хотите просмотреть значения параметров, можно написать код ведения журнала, чтобы получить значения параметров из Parameters свойства DbCommand объекта, полученного в методах перехватчика.
Обратите внимание, что этот тест нельзя повторить, пока приложение не будет перезапущено. Если вы хотите иметь возможность проверить устойчивость подключения несколько раз в одном запуске приложения, можно написать код для сброса счетчика ошибок в SchoolInterceptorTransientErrors .
Чтобы увидеть разницу в стратегии выполнения (политика повтора), закомментируйте SetExecutionStrategy строку в счулконфигуратион. CS, снова запустите страницу students в режиме отладки и выполните поиск по запросу "Throw".
На этот раз отладчик останавливается на первом созданном исключении сразу же после того, как он пытается выполнить запрос в первый раз.
Раскомментируйте строку сетексекутионстратеги в счулконфигуратион. CS.
Получите код
Дополнительные ресурсы
ссылки на другие ресурсы Entity Framework можно найти в ASP.NET ресурсах, рекомендуемых для доступа к данным.
Дальнейшие действия
В этом учебнике рассмотрены следующие задачи.
- Включена устойчивость подключения
- Включено перехват команд
- Тестирование новой конфигурации
перейдите к следующей статье, чтобы узнать о Code First миграции и развертывании Azure.