2016-05-13 6 views
3

У меня есть класс службы команд, который использует единицу шаблона работы, с различными методами для обновления базы данных (в этом случае SQL Azure) через сущность.Вложенные транзакции EF6

Служба команд получает экземпляр с ссылкой на экземпляр dbcontext, чье жизненное время управляется моей картой DI по выбору.

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

public void UpdateStuff(someEntity) 
{ 
    using(var tx = _db.Database.BeginTransaction()) 
    { 
     //Some updates to db 
     _db.SaveChanges(); 
     //Some other updates to db 
     _db.SaveChanges(); 
     tx.Commit(); 
    } 
} 

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

public void UpdateWithSomeCascadingStuff(someOtherEntity) 
{ 
    using(var tx = _db.Database.BeginTransaction()) 
    { 
     //Some updates to db 
     _db.SaveChanges(); 

     //Some other cascading logic and updates to db 
     var relatedEntityToUpdate = _query.GetSomeEntityToUpdate(someOtherEntity); 
     UpdateStuff(relatedEntityToUpdate); 
     _db.SaveChanges(); 
     tx.Commit(); 
    } 
} 

Очевидно, что, делая это, я гнездование EF сделки по тому же DbContext экземпляра.

Поддерживается ли это, и это вызовет проблемы? Есть ли альтернативные подходы, которые я могу предпринять?

UPDATE: Я использую EF6 Code First

ответ

1

DBContexts EntityFramework в реализует как UnitOfWork и Repository модели сами по себе.

Контекст в EF6 также автоматически обертывает все фиксации в транзакции сам по себе (если он еще не является частью одного).

Итак, нет, вы не должны делиться контекстом между несколькими единицами работы. Они должны каждый получить свои собственные.

UPDATE

Если вы попытаетесь запустить повторяющиеся операции на одном DbContext вы получите:

An unhandled exception of type 'System.InvalidOperationException' occurred in EntityFramework.dll 

Additional information: The connection is already in a transaction and cannot participate in another transaction. EntityClient does not support parallel transactions. 

Так нет, вы не можете делать то, что вы просите.

+0

Спасибо, но это не отвечает на мой вопрос. –

+1

EF скрыт за интерфейсом от клиентского кода (поскольку мне нужно иметь возможность легко вытеснять механизмы хранения, не затрагивая клиентский код), а также выполнять некоторые CQRS. Поэтому мне пришлось «обернуть» свою реализацию UOW. Как, почему и правильность этого - слишком продолжительная дискуссия. Я знаю, что EF обертывает инструкции перед SaveChanges в одной транзакции. В моем сценарии у меня есть mutliple вызовы SaveChanges, которые мне нужно обернуть в одну транзакцию. Еще раз - не здесь, чтобы защитить дизайн - я просто хочу узнать, могу ли я вложить транзакции EF6 внутри друг друга. –

+1

Я расширил свой ответ. Надеюсь, что поможет ответить на ваш вопрос лучше. –

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