How to Properly Handle Transactions in EF Core

How to Properly Handle Transactions in EF Core

Ever run into a situation where part of your database updates succeed, but others fail, leaving your data in a messy, inconsistent state? That’s exactly what transactions are designed to prevent.

A transaction ensures that a set of operations happens completely or not at all. If everything goes smoothly, the changes are saved (commit). But if something goes wrong, the database rolls everything back, as if nothing ever happened. This is crucial when dealing with multiple inserts, updates, or deletes that must stay in sync.

In Entity Framework Core (EF Core), handling transactions correctly can save you from frustrating bugs, data corruption, and unexpected failures. In this post, we’ll break down how transactions work in EF Core.

Understanding How EF Core Manages Transactions

By default, EF Core takes care of transactions for you. Whenever you call SaveChanges() or SaveChangesAsync(), EF Core automatically wraps all pending database operations in a transaction. If everything succeeds, the changes are committed, if something goes wrong, EF Core rolls everything back to keep your data consistent.

Here’s what happens under the hood when you call SaveChangesAsync():

  1. EF Core begins a transaction before applying changes to the database.
  2. It executes all pending inserts, updates, or deletes.
  3. If everything is successful, the transaction is committed.
  4. If an error occurs, EF Core automatically rolls back the transaction.
C#
				using var context = new InventoryContext();

context.Products.Add(new Product
{
    Name = Name,
    Price = Price
});

var category = await context.Categories.FirstOrDefaultAsync(c => c.Id == CategoryId);

category.ProductCount += 1;

// EF Core automatically begins a transaction here when SaveChanges is called
await context.SaveChangesAsync();
			

This built-in transaction management works well for most cases, but sometimes you need manual control, especially when dealing with multiple database operations that must be executed together.

Manual Transaction Management

One way to achieve this is by manually creating a transaction using the Database property on your DbContext and calling BeginTransaction().

Imagine a scenario where you’re executing several database operations, such as inserting an order and updating product stock. Without a manual transaction, each of these operations would run in its own transaction. This approach can leave the database in an inconsistent state if an error occurs after the first operation has been successfully committed.

By wrapping multiple operations in a single transaction, you ensure that they are either all committed together or none at all, maintaining the integrity of your data.

C#
				using var context = new MyDbContext();
using var transaction = context.Database.BeginTransaction();

try
{
    var order = new Order
    {
        OrderDate = model.OrderDate,
        CustomerId = model.CustomerId,
        TotalAmount = model.TotalAmount
    };
    context.Orders.Add(order);

    // Save changes for the order
    context.SaveChanges();

    var product = context.Products.FirstOrDefault(p => p.Id == model.ProductId);

    product.StockQuantity -= 1;

    // Save changes for the product
    context.SaveChanges();

    // Commit the transaction if everything is successful
    transaction.Commit();
}
catch (Exception ex)
{
    // Rollback the transaction if an error occurs
    transaction.Rollback();
}

			

Conclusion

In summary, managing transactions in Entity Framework Core is essential for ensuring data integrity. While EF Core handles transactions automatically in many cases, manual control is necessary when dealing with multiple operations that must be executed together.

By using BeginTransaction(), Commit(), and Rollback(), you can ensure that your operations are atomic and consistent. Mastering this approach will help you build more reliable applications and maintain the integrity of your data.

See you next time!

Share the Post:
plugins premium WordPress