Я изучал транзакции, и кажется, что они заботятся о себе в EF, пока я перехожу false
к, SaveChanges()
а затем звоню, AcceptAllChanges()
если нет ошибок:
SaveChanges(false);
// ...
AcceptAllChanges();
Что если что-то пойдет не так? мне не нужно откатывать или, как только мой метод выходит из области видимости, транзакция заканчивается?
Что происходит с какими-либо столбцами отступов, которые были назначены на полпути через транзакцию? Я предполагаю, что если кто-то еще добавил запись после моей, пока моя не испортилась, это означает, что будет отсутствовать значение Identity.
Есть ли причина использовать стандартный TransactionScope
класс в моем коде?
c#
entity-framework
transactions
Марк Смит
источник
источник
SaveChanges(fase); ... AcceptAllChanges();
был шаблон в первую очередь. Обратите внимание, как принятый ответ на вышеупомянутый вопрос написан автором блога - и на этот блог есть ссылка в другом вопросе. Это все вместе.Ответы:
С Entity Framework большей части времени
SaveChanges()
достаточно. Это создает транзакцию или участвует в любой внешней транзакции и выполняет всю необходимую работу в этой транзакции.Иногда, хотя
SaveChanges(false) + AcceptAllChanges()
спаривание полезно.Самое полезное место для этого - ситуации, когда вы хотите выполнить распределенную транзакцию в двух разных контекстах.
Т.е. как то так (плохо)
Если
context1.SaveChanges()
успешно, ноcontext2.SaveChanges()
не удается, вся распределенная транзакция прерывается. Но, к сожалению, Entity Framework уже отменил измененияcontext1
, поэтому вы не можете воспроизвести или эффективно зарегистрировать ошибку.Но если вы измените свой код, чтобы он выглядел так:
В то время как вызов
SaveChanges(false)
отправляет необходимые команды в базу данных, сам контекст не изменяется, поэтому вы можете сделать это снова, если необходимо, или вы можете опросить,ObjectStateManager
если хотите.Это означает, что если транзакция фактически выдает исключение, которое вы можете компенсировать, повторяя попытку или регистрируя состояние каждого контекста
ObjectStateManager
где-либо.Смотрите мой блог для получения дополнительной информации.
источник
SaveChanges(false)
выполняет фактическое обновление базы данных, аAcceptAllChanges()
EF говорит: «Хорошо, вы можете забыть, какие вещи нужно сохранить, потому что они были успешно сохранены». Если произойдетSaveChanges(false)
сбой,AcceptAllChanges()
он никогда не будет вызван, и EF все равно будет рассматривать ваш объект как имеющий свойства, которые были изменены и должны быть сохранены обратно в базу данных.Если вы используете EF6 (Entity Framework 6+), это изменилось для вызовов базы данных в SQL.
См .: http://msdn.microsoft.com/en-us/data/dn456843.aspx
использовать context.Database.BeginTransaction.
Из MSDN:
источник
throw;
фрагмент MSDN и четко указал, что это не оригинал из статьи MSDN.Rollback()
вызывается в случае, если он обращается к MySql или к чему-то, что не имеет такого автоматического поведения.Поскольку некоторая база данных может выдать исключение в dbContextTransaction.Commit (), лучше это:
источник
false
вcontext.SaveChanges();
, и дополнительно позвонитьcontext.AcceptAllChanges();
.