Entity Framework入門教程(19)---EF中使用事務


EF中使用事務

這節介紹EF6中事務的使用。EF core中事務的使用方式和EF6中一模一樣。

1.EF中的默認的事務

  默認情況下,當我們執行一個SaveChanges()方法時就會新建了一個事務,然后將context中的CUD操作都在這個事務中進行。Context中有多個SaveChanges()時,每一個SaveChanges()都會執行一個單獨的事務。一個栗子:

using (var context = new SchoolContext())
{
    context.Database.Log = Console.Write;

    var standard = context.Standards.Add(new Standard() { StandardName = "1st Grade" });

    context.Students.Add(new Student()
    {
        FirstName = "Rama",
        StandardId = standard.StandardId
    });

    context.SaveChanges();

    context.Courses.Add(new Course() { CourseName = "Computer Science" });
    context.SaveChanges();
}

上邊的代碼執行結果如下:

從上邊的栗子我們可以清楚地看到每個SaveChanges()方法都開啟了一個事務。這時有一個問題:有沒有什么辦法讓多個SaveChanges()在一個事務中執行呢?這樣的話就可以減少事務創建、開啟進而提升性能了。

2.一個事務執行多個SaveChanges()方法

EF6和EF core中提供了兩種方法實現在一個事務中執行多個SaveChanges()方法。

DbContext.Database.BeginTrasaction():新建一個事務,在新建的事務內進行context.SaveChanges()

DbContext.Database.UseTransaction(trans):使用一個context作用域外的現有的事務,多個context都可以在通過這個事務一起提交。

1.DbContext.Database.BeginTrasaction()

一個栗子:

using (var context = new SchoolContext())
{
    context.Database.Log = Console.Write;

    using (DbContextTransaction transaction = context.Database.BeginTransaction())
    {
        try
        {
            var standard = context.Standards.Add(new Standard() { StandardName = "1st Grade" });

            context.Students.Add(new Student()
            {
                FirstName = "Rama",
                StandardId = standard.StandardId
            });
            context.SaveChanges();
            // 第一個SaveChanges()方法后拋出異常
            throw new Exception();

            context.Courses.Add(new Course() { CourseName = "Computer Science" });
            context.SaveChanges();

            transaction.Commit();
        }
        catch (Exception ex)
        {
            transaction.Rollback();
            Console.WriteLine("Error occurred.");
        }
    }
}

執行結果:

我們可以看到所有的SaveChanges()都被回滾了。如果把拋出異常的代碼注釋掉那么執行效果如下:

2.DbContext.Database.UseTransaction(trans)

使用DbContext.Database.UseTransaction(trans),我們通過參數傳入的是一個作用域外的事務,注意這里EF不會再新建內置的事務,而是使用通過參數傳入的事務

一個栗子:

private static void Main(string[] args)
{
    string providerName = "System.Data.SqlClient";
    string serverName = ".";
    string databaseName = "SchoolDB";

    // 目標數據庫
    SqlConnectionStringBuilder sqlBuilder =new SqlConnectionStringBuilder();
    sqlBuilder.DataSource = serverName;
    sqlBuilder.InitialCatalog = databaseName;
    sqlBuilder.IntegratedSecurity = true;

    using (SqlConnection con = new SqlConnection(sqlBuilder.ToString()))
    {
        con.Open();
     //在DbContext作用域外新建一個事務
        using (SqlTransaction transaction = con.BeginTransaction())
        {
            try
            {
         //使用上邊的創建的事務
                using (SchoolContext context = new SchoolContext(con, false))
                {
                    context.Database.UseTransaction(transaction);

                    context.Students.Add(new Student() { Name = "Ravi" });
                    context.SaveChanges();
                }

                using (SchoolContext context = new SchoolContext(con, false))
                {
                    context.Database.UseTransaction(transaction);

                    context.Grades.Add(new Standard() { GradeName = "Grade 1", Section = "A" });
                    context.SaveChanges();
                }
                transaction.Commit();
            }
            catch (Exception ex)
            {
                transaction.Rollback();

                Console.WriteLine(ex.InnerException);
            }
        }
    }
}

 

EF系列目錄鏈接:Entity Franmework系列教程匯總


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM