Каков уровень изоляции транзакций по умолчанию в Entity Framework, когда я выдаю “SaveChanges()”?

#.net #entity-framework #ado.net #transactions

#.net #entity-framework #ado.net #транзакции

Вопрос:

Каков уровень изоляции транзакций по умолчанию в Entity Framework при выпуске SaveChanges() ? Я нигде не могу его найти. Должно ли это быть Serializable ?

Ответ №1:

SaveChanges использует реализацию DbTransaction для текущего поставщика хранилища. Это означает, что уровень изоляции транзакций по умолчанию установлен на значение по умолчанию для сервера базы данных. В SQL Server это READ COMMITTED . Если вы хотите изменить уровень изоляции, вы можете использовать TransactionScope . Вы также можете переопределить SaveChanges в своем производном контексте и перенести base.SaveChanges() в область видимости непосредственно в переопределенный метод.

 public override void SaveChanges()
{
    // Default isolation level for TransactionScope is Serializable
    using (var scope = new TransactionScope())
    {
        base.SaveChanges();
        scope.Complete();
    }
}
  

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

Редактировать: уровень транзакции по умолчанию в EF6 изменился на READ COMMITTED SNAPSHOT

Комментарии:

1. Разве это не было бы бесполезно, поскольку код должен выполняться в рамках самой транзакции?

2. возможно, необходимо включить base.savechanges в try cacth, просто чтобы выполнить scope.complete, если base.savechanges завершится неудачей: catch e { scope.complete(); throw } .

3. @ChadMoran, можете ли вы объяснить свой комментарий?

4. Дополнительные данные по этому ответу здесь: Советы по предотвращению взаимоблокировок в приложениях Entity Framework

5. @Ladislav Mrnka, Возможно, я ошибаюсь, но «READ_COMMITTED_SNAPSHOT» не должен быть уровнем изоляции. Это должна быть опция, которую можно установить, чтобы изменить поведение уровня изоляции «READ_COMMITTED». С другой стороны, как EF может использовать «READ_COMMITTED_SNAPSHOT» по умолчанию, если эта опция должна быть явно включена на сервере SQL? Уровни изоляции задокументированы здесь msdn.microsoft.com/en-us/library/ms173763.aspx , кстати, по той же ссылке мы можем найти объяснение опции READ_COMMITTED_SNAPSHOT. Я что-то упускаю?

Ответ №2:

По умолчанию система.Инфраструктура транзакций создает сериализуемые транзакции.

Ответ №3:

Начиная с EF 6, уровень изоляции по умолчанию для транзакции SQL Server ЗАФИКСИРОВАН для ЧТЕНИЯ. Ссылка здесь: Entity Framework, работающий с транзакциями (начиная с EF6)

Для других поставщиков (та же ссылка) «уровень изоляции транзакции — это любой уровень изоляции, который поставщик базы данных считает своим значением по умолчанию». Итак, вам придется взглянуть на документацию этого поставщика.