2014-10-23 2 views
2

В моем проекте инъекция зависимости будет создавать экземпляр DomainContext (Entity Framework 6 DbContext) для каждого запроса. Мне интересно, какой будет правильный курс действий, касающийся транзакций. Я знаю, что SaveChanges будет использовать транзакцию внутри страны.Что такое явная транзакция базы данных в Entity Framework 6?

Должен ли я беспокоиться о возможных изменениях, которые остались в DomainContext?

Я думал, что использование явных транзакций может оградить меня от этого дела, как в:

public class FooService : IFooService 
{ 
    private DomainContext db; 

    public FooService(DomainContext db) 
    { 
     this.db = db; 
    } 

    public void MergeEntities(Entity source, Entity target) 
    { 
     using (var uow = db.Database.BeginTransaction()) 
     { 
      // merge source into target 

      db.SaveChanges(); 

      uow.Commit(); 
     } 
    } 
} 

Я не уверен, если я должен просто использовать это вместо того, чтобы он мог дать мне такую ​​же защиту:

public class FooService : IFooService 
{ 
    private DomainContext db; 

    public FooService(DomainContext db) 
    { 
     this.db = db; 
    } 

    public void MergeEntities(Entity source, Entity target) 
    { 
     // merge source into target 

     db.SaveChanges(); 
    } 
} 
+0

Не знаю, правильно это или нет, но насколько я знаю, транзакции влияют только на состояние базы данных. Любые контекстные операции не ограничены транзакцией, поэтому, если вы завершаете слияние транзакции, вы все равно можете столкнуться с беспорядком, если операция слияния идет не так - в этом случае вы должны отказаться от контекста и начать заново. В этот момент ничто не попало в БД - работа выполняется в БД во время 'SaveChanges' – Charleh

ответ

1

DbContext.SaveChanges() является атомарным и будет автоматически выполняться под его собственной транзакцией. Таким образом, ваш второй пример достаточно.

DbContext и метод SaveChanges() - это реализация шаблона Единицы работы в Entity Framework.

Database.BeginTransaction() создает транзакцию в базовой базе данных, а также позволяет вызывающему абоненту установить необязательный IsolationLevel. Это транзакция на совершенно ином уровне в архитектуре. Это то, что я, вероятно, никогда не буду использовать, поскольку мне не нравится иметь какую-либо бизнес-логику в базе данных, но я уверен, что для использования в устаревших системах существует множество возможностей.

+0

Хорошо, так в какой ситуации был бы подходящим первый пример? – Korijn

+0

Я бы использовал транзакцию, когда я не использую EF и не вношу изменений в несколько таблиц. Я также использовал транзакции при внесении изменений в различные контексты и другие источники, которые участвуют в транзакциях. Возможно, вам потребуется включить службу MSDTC при использовании транзакций в нескольких источниках. –

+0

Правильно, поэтому я получаю это, но в чем смысл использования 'db.Database.BeginTransaction()'? Мне кажется, что для этого нет смысла; но он никогда не был бы добавлен в структуру, если это действительно так. – Korijn

1

Вы можете попробовать использовать Unit Test, чтобы доказать, что EF использует транзакцию.
Попробуйте вставить несколько строк, и одна из строк содержит недопустимые данные.
Затем используйте SaveChanges(), чтобы сохранить эти несколько записей в базе данных.
Если все или некоторые записи были отброшены назад, то EF использует транзакцию.

Или единица измерения работы или сделка хороша.
Или вы также можете использовать приведенный ниже код для проверки изменений на DbContext:.
DbContext.ChangeTracker.Entries() Любой (е => e.State == EntityState.Added
|| e.State == EntityState.Modified
|| e.State == EntityState.Deleted);

+0

Я вижу, что вы говорите, я знаю, как работают транзакции, но что такое добавленная ценность 'db.Database.BeginTransaction()'? Мне кажется, что для этого нет смысла; но он никогда не был бы добавлен в структуру, если это действительно так. – Korijn

Смежные вопросы