Transactions in Entity Framework

Transactions in Entity Framework with Examples

In this article, I am going to discuss How to use Transactions in Entity Framework Database First Approach with Examples. Please read our previous article where we discussed How to use Database View in Entity Framework Database First Approach. We are going to work with the same example that we created in our Introduction to Entity Framework Database First Approach article. Please read our Introduction to Entity Framework Database First article before proceeding to this article.

What is a Transaction?

A Transaction is a set of operations (multiple DML Operations) that ensures either all database operations succeeded or all of them failed to ensure data consistency. This means the job is never half done, either all of it is done or nothing is done.

Transactions in Entity Framework

In Entity Framework, the SaveChanges() method internally creates a transaction and wraps all the INSERT, UPDATE and DELETE Statements. If we are calling the SaveChanges() multiple times, then it will create multiple transactions i.e. one transaction per SaveChanges method call to perform CRUD operations. In each transaction, if the command is executed successfully, then will commit that transaction else rollback that transaction.

For a better understanding, please have a look at the following example. In the below example, we use context.Database.Log to log the generated database transactions, SQL Statements, and whether the transaction rollback or commits into the console window. Here, first, we created and add new Standard and Student entities into the context object and then call the SaveChanges method to save them into the database. After this, we again add a new Course entity into the context object and then call the SaveChanges() method to save the Course entity into the database. The following example code is self-explained, so please go through the comment lines.

using System;
namespace DBFirstApproach
{
    class Program
    {
        static void Main(string[] args)
        {
            using (EF_Demo_DBEntities context = new EF_Demo_DBEntities())
            {
                //To See the Generated Transaction, SQL Commands
                context.Database.Log = Console.Write;

                //Creating a New Standard
                Standard standard = new Standard() { StandardName = "New Standard" };

                //Adding the new standard with the context object
                context.Standards.Add(standard);

                //Creating a New Student
                Student student = new Student()
                {
                    FirstName = "Pranaya",
                    LastName = "Rout",
                    StandardId = standard.StandardId
                };

                //Adding the new Student with the context object
                context.Students.Add(student);

                //Calling the SaveChanges method
                //It will Create a New Transaction and Execute both INSERT Statement within that Transaction
                context.SaveChanges();
                Console.WriteLine();
                //Creating a New Course
                Course course = new Course() { CourseName = "Entity Framework" };

                //Adding the new Course with the context object
                context.Courses.Add(course);

                //Calling the SaveChanges method
                //It will Create a New Transaction and Execute the INSERT Statement within that Transaction
                context.SaveChanges();
            }

            Console.Read();
        }
    }
}

Now, run the application, and please observe the output.

Transactions in Entity Framework

As you can see in the above output, it created two transactions. The first transaction will be created when we call the SaveChanges method first and using this transaction, it will generate and execute the INSERT Command to insert the Standard and Student Entities into the Standard and Student database and tables and then commit the transaction. The second transaction is created when we call the SaveChanges for the second time and using this transaction, it will generate and execute the INSERT command insert the Course Entity into the Course database table and then commit the transaction. So, the point that you need to remember is each SaveChanges() method call will create a brand-new transaction and executes the corresponding database commands using that transaction.

Multiple SaveChanges in a Single Transaction using Entity Framework Database First Approach

Entity Framework 6 allow us to create or use a single transaction with multiple SaveChanges() method call using the following two approaches:

  1. DbContext.Database.BeginTransaction(): This will create a new Transaction object for the underlying database and allow us to commit or roll back changes made to the database using multiple SaveChanges method calls. If this is not clear at the moment, don’t worry we will try to understand this with examples.
  2. DbContext.Database.UseTransaction(): This allows us to pass an existing Transaction object created out of the scope of a context object. This will allow Entity Framework to execute commands within an external transaction object. If this is not clear at the moment, don’t worry we will try to understand this with examples.
Example to Understand DbContext.Database.BeginTransaction() in Entity Framework

Let us first understand DbContext.Database.BeginTransaction() in Entity Framework with an example. In the below example, we are creating a new transaction object using DbContext.Database.BeginTransaction() method. And within this transaction object, we are calling SaveChanges() multiple times and finally, if everything is fine we are calling the Commit method on the transaction object to save the changes permanently in the database. If anything goes wrong, we are calling the Rollback method which will roll back the changes in the database which are made the by SaveChanges method. The following example is self-explained, so please go through the comment lines.

using System;
using System.Data.Entity;
namespace DBFirstApproach
{
    class Program
    {
        static void Main(string[] args)
        {
            using (EF_Demo_DBEntities context = new EF_Demo_DBEntities())
            {
                //To See the Generated Transaction, SQL Commands by the context object
                context.Database.Log = Console.Write;

                //It will create a Transaction
                using (DbContextTransaction transaction = context.Database.BeginTransaction())
                {
                    try
                    {
                        //Creating a New Standard
                        Standard standard = new Standard() { StandardName = "New Standard" };

                        //Adding the new standard with the context object
                        context.Standards.Add(standard);

                        //Creating a New Student
                        Student student = new Student()
                        {
                            FirstName = "Pranaya",
                            LastName = "Rout",
                            StandardId = standard.StandardId
                        };

                        //Adding the new Student with the context object
                        context.Students.Add(student);

                        //Calling the SaveChanges method
                        //Now, it will not Create a New Transaction 
                        //It is going to Execute both INSERT Statement within the Transaction which is creating
                        //using context.Database.BeginTransaction() method
                        context.SaveChanges();
                        Console.WriteLine();

                        //Creating a New Course
                        Course course = new Course() { CourseName = "Entity Framework" };

                        //Adding the new Course with the context object
                        context.Courses.Add(course);

                        //Now, it will not Create a New Transaction 
                        //It is going to Execute the INSERT Statement within the Transaction which is creating
                        //using context.Database.BeginTransaction() method
                        context.SaveChanges();

                        //The following method will commit the transaction and changes are made permanently within the database
                        transaction.Commit();
                        Console.WriteLine($"Transaction Successful");
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine($"Transaction Failed : Message - {ex.Message}");
                        //The following method will roll back the transaction and changes are rolled back from the database
                        transaction.Rollback();
                    }
                }
            }

            Console.Read();
        }
    }
}
Output:

Example to Understand DbContext.Database.BeginTransaction() in Entity Framework

As you can see in the above output, all three INSERT Statements are executed within a single transaction and once all three statements are executed successfully, it commits the transaction. If an exception occurs, then the changes made by the SaveChanges method in the database will be rolled back. For a better understanding, please have a look at the following example. Here, after the first SaveChanges method, we throw some exceptions and the catch block is going to handle that exception and roll back the transaction by calling the Rollback method on the transaction object. In this case, the data INSERTED into the database using the first SaveChanges method will be rollback.

using System;
using System.Data.Entity;
namespace DBFirstApproach
{
    class Program
    {
        static void Main(string[] args)
        {
            using (EF_Demo_DBEntities context = new EF_Demo_DBEntities())
            {
                //To See the Generated Transaction, SQL Commands by the context object
                context.Database.Log = Console.Write;

                //It will create a Transaction
                using (DbContextTransaction transaction = context.Database.BeginTransaction())
                {
                    try
                    {
                        //Creating a New Standard
                        Standard standard = new Standard() { StandardName = "Excellent Standard" };

                        //Adding the new standard with the context object
                        context.Standards.Add(standard);

                        //Creating a New Student
                        Student student = new Student()
                        {
                            FirstName = "Bikash",
                            LastName = "Kumar",
                            StandardId = standard.StandardId
                        };

                        //Adding the new Student with the context object
                        context.Students.Add(student);

                        //Calling the SaveChanges method
                        //Now, it will not Create a New Transaction 
                        //It is going to Execute both INSERT Statement within the Transaction which is creating
                        //using context.Database.BeginTransaction() method
                        context.SaveChanges();
                        Console.WriteLine();

                        //Creating a New Course
                        Course course = new Course() { CourseName = "Advanced C#.NET" };

                        //Throwing exceptiopn to test the rollback transaction functionality
                        throw new Exception("Some Unknown Error Occurred");

                        //Adding the new Course with the context object
                        context.Courses.Add(course);

                        //Now, it will not Create a New Transaction 
                        //It is going to Execute the INSERT Statement within the Transaction which is creating
                        //using context.Database.BeginTransaction() method
                        context.SaveChanges();

                        //The following method will commit the transaction and changes are made permanently within the database
                        transaction.Commit();
                        Console.WriteLine($"Transaction Successful");
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine($"Transaction Failed : Message - {ex.Message}");
                        //The following method will roll back the transaction and changes are rolled back from the database
                        transaction.Rollback();
                    }
                }
            }

            Console.Read();
        }
    }
}

Now, run the above code and you will get the following output. As expected, the transaction is rollback and you can also verify the database, and you will see the above Standard and Student information will not be there in the Standard and Student database table.

How to use the Transaction in Entity Framework Database First Approach with Examples

Note: We will discuss DbContext.Database.UseTransaction() method in our Entity Framework Code First Approach Articles.

In the next article, I am going to discuss How to Validate Entities in Entity Framework Database First Approach with Examples. Here, in this article, I try to explain How to use the Transaction in Entity Framework Database First Approach with Examples. I hope you enjoy this How to use Transaction in Entity Framework Database First Approach article.

Leave a Reply

Your email address will not be published. Required fields are marked *