Entity Framework Core 2.1: Ambient Transactions (new functionality!)

As we have mentioned, Entity Framework Core allows us to work with transactions. The idea of a transaction is that you can consider a set of operations as if it were one, so that if one of the operations fails, all other operations are discarded and no change is applied to the database. Though you have freedom to, after performing an operation, reverse it without the need of any type of error having occurred. The way to make the changes made is saved using the SaveChanges function.

When we do several operations on the Data Context (the class that inherits from DbContext), we can use the SaveChanges function so that these operations are performed in the database. If we do not use SaveChanges, and destroy the instance of  the Data Context, then the changes made will be discarded.

If you wish, you can have more control over the transactions, where you can even reverse the changes made by the SaveChanges function. This is useful when you need to perform a set of complex operations, where you need to, at least temporarily, have some of the operations reach the database, and, if something fails, you can still reverse the changes made. For this we use the BeginTransaction function.

In the following example we will use BeginTransaction to add a student to the database, we will save the changes, we will obtain the student’s Id, and then we will revert the operation:

using (var context = new ApplicationDbContext())
{
    using (var transaction = context.Database.BeginTransaction())
    {
        var student1 = new Student();
        student1.Name = "Robert Fatou";
        context.Add(student1);
        context.SaveChanges();
        // The Id will have a valid value
        Console.WriteLine(student1.Id);
        // Let's revert the operation
        transaction.Rollback();
    }
}

The previous example shows that the insertion operation was performed at the database level, and we obtained a valid Id, then, we saw that we can revert the operation using the RollBack function. If we want the operation to be maintained in the database, we must execute the transaction.Commit() function.

Ambient Transaction

Now that we know what a transaction is, it is important to talk about ambient transactions. An ambient transaction is one that works at the thread level. Thus, all operations that occur in that context will be part of the transaction.

From Entity Framework Core 2.1 we can use the ambient transactions in our operations with EF Core.

Let’s see an example:

static void Main(string[] args)
{
    using (var scope = new TransactionScope())
    {
        CreateStudent();
        CreateCourse();
        // Uncomment the following line if you want to
        // have the previous operations persisted in the Database
        //scope.Complete();
    }
}

private static void CreateCourse()
{
    using (var context = new ApplicationDbContext())
    {
        var course = new Course();
        course.Name = "Programming I";
        context.Add(course);
        context.SaveChanges();
    }
}

private static void CreateStudent()
{
    using (var context = new ApplicationDbContext())
    {
        var student1 = new Student();
        student1.Name = "Transaction Scope";
        context.Add(student1);
        context.SaveChanges();
    }
}

In the previous example we see that we have the CreateCourse and CreateStudent methods which, by their own, instantiate their own Data Context, use it, and save changes. However, given that both operations occur within the context of an ambient transaction, we have the ability to reverse both operations and we desire it. For this, all we have to do is not call the Complete method of TransactionScope.

2 comments

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s