Данное руководство устарело. Актуальное руководство: Руководство по Entity Framework Core
Когда мы вызываем при добавлении, обновлении, удалении метод SaveChanges()
, то фактически Entity Framework проводит транзакцию.
В приложении на C# мы также управлять транзакциями. Когда може быть полезно ручное управление транзакциями? Транзакции применяются чаще всего для того,
чтобы выполнить последовательность операций, которые должны отличаться высокой согласованностью, и при этом иметь возможность
откатить все сделанные из этих операций назад, если какая-нибудь из этих операций завершилась с ошибкой.
Для создания транзакции используется выражение var transaction = db.Database.BeginTransaction()
, и так как класс
DbContextTransaction реализует интерфейс IDisposable, то весь код транзакции обертываем в конструкцию using
После операций с БД вызывается метод transaction.Commit()
для коммита транзакции.
Рассмотрим на примере:
using(UserContext db = new UserContext()) { db.Database.Log = Console.Write; using (var transaction = db.Database.BeginTransaction()) { try { db.Database.ExecuteSqlCommand(@"UPDATE People SET Age = Age + 1 WHERE Name = 'Sam'"); db.People.Add(new Person { Age = 34, Name = "Bob" }); db.SaveChanges(); transaction.Commit(); } catch (Exception ex) { transaction.Rollback(); } } foreach(Person p in db.People.ToList()) Console.WriteLine("Name: {0} Age: {1}",p.Name, p.Age); }
В данном случае и метод db.Database.ExecuteSqlCommand
и db.SaveChanges()
определяют две разные транзакции. Однако поскольку мы оборачиваем оба этих метода в
блок using (var transaction = db.Database.BeginTransaction())
оба этих метода будут объединены в одну транзакцию. И если
вызов db.Database.ExecuteSqlCommand
пройдет неудачно, то вызов db.SaveChanges()
не будет выполняться.
Однако если, допустим, у нас возникнет исключение параллелизма или любое другое исключение при редактировании или добавлении, то есть одна из
операций (или обе) завершатся неудачно, то они в целом смысла уже не будут иметь. Поэтому надо будет откатить все сделанные изменения с
помощью метода transaction.Rollback()