Управление транзакциями

Данное руководство устарело. Актуальное руководство: Руководство по Entity Framework Core

Последнее обновление: 22.12.2017

Когда мы вызываем при добавлении, обновлении, удалении метод 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()

Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850