Примечание.
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Замечание
Entity Framework 6.1 и новее — функции, API и т. д., рассмотренные на этой странице, были представлены в Entity Framework 6.1. Если вы используете более раннюю версию, некоторые или все сведения не применяются.
В рамках версии 6.1 мы представляем новую функцию устойчивости подключения для EF: возможность обнаруживать и восстанавливаться автоматически, когда временные сбои подключения влияют на подтверждение фиксаций транзакций. Полные сведения о сценарии лучше всего описаны в записи блога о подключении к базе данных SQL и проблеме idempotency. В итоге сценарий заключается в том, что при возникновении исключения во время фиксации транзакции существует две возможные причины:
- Сбой фиксации транзакции на сервере
- Фиксация транзакции успешно выполнена на сервере, но из-за проблемы с подключением уведомление об этом не дошло до клиента.
Когда происходит первая ситуация, приложение или пользователь могут повторить действие, но во второй ситуации следует избегать повторных попыток, и приложение может восстановиться автоматически. Проблема заключается в том, что без возможности обнаруживать фактическую причину, по которой было сообщено исключение во время фиксации, приложение не может выбрать правильный курс действия. Новая функция в EF 6.1 позволяет EF дважды проверить базу данных, если транзакция прошла успешно и провести правильный курс действий прозрачно.
Использование компонента
Чтобы включить необходимую функцию, включите вызов SetTransactionHandler в конструктор dbConfiguration. Если вы не знакомы с DbConfiguration, см. раздел "Конфигурация на основе кода". Эту функцию можно использовать в сочетании с автоматическими повторными попытками, представленными в EF6, что помогает в ситуации, в которой транзакция фактически не смогла совершить запись на сервере из-за кратковременного сбоя.
using System.Data.Entity;
using System.Data.Entity.Infrastructure;
using System.Data.Entity.SqlServer;
public class MyConfiguration : DbConfiguration
{
public MyConfiguration()
{
SetTransactionHandler(SqlProviderServices.ProviderInvariantName, () => new CommitFailureHandler());
SetExecutionStrategy(SqlProviderServices.ProviderInvariantName, () => new SqlAzureExecutionStrategy());
}
}
Отслеживание транзакций
Если эта функция включена, EF автоматически добавит новую таблицу в базу данных с именем __Transactions. Новая строка вставляется в эту таблицу каждый раз, когда транзакция создается с помощью EF, и эта строка проверяется на наличие, если во время фиксации транзакции происходит сбой транзакции.
Хотя EF будет делать лучшие усилия, чтобы обрезать строки из таблицы, если они больше не нужны, таблица может расти, если приложение завершается преждевременно, и по этой причине может потребоваться очистить таблицу вручную в некоторых случаях.
Обработка сбоев коммита с предыдущими версиями
До EF 6.1 не было механизма обработки сбоев фиксации в продукте EF. Существует несколько способов решения этой ситуации, которые можно применить к предыдущим версиям EF6:
Вариант 1. Ничего не делать
Вероятность сбоя подключения во время фиксации транзакции низка, поэтому для приложения может быть приемлемо просто завершить работу с ошибкой, если это условие действительно произойдет.
Вариант 2. Использование базы данных для сброса состояния
- Удалите текущий DbContext
- Создайте новый DbContext и восстановите состояние вашего приложения из базы данных
- Сообщите пользователю, что последняя операция не была выполнена успешно
Вариант 3. Отслеживание транзакции вручную
- Добавьте не отслеживаемую таблицу в базу данных, используемую для отслеживания состояния транзакций.
- Вставьте строку в таблицу в начале каждой транзакции.
- Если соединение завершается ошибкой во время фиксации изменений, проверьте наличие соответствующей строки в базе данных.
- Если строка присутствует, продолжайте в обычном режиме, так как транзакция была успешно зафиксирована.
- Если строка отсутствует, используйте стратегию выполнения, чтобы повторить текущую операцию.
- Если фиксация выполнена успешно, удалите соответствующую строку, чтобы избежать роста таблицы.
В этой записи блога содержится пример кода для выполнения этого в SQL Azure.