EF 自带事务

通过反编译可以看到单实例DbContext的SaveChanges方式默认开启了事务,当同时更新多条记录时,有一条失败就会RollBack。模拟测试代码

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using EF.Model;
using EF.DAL;
using System.Data.Entity;
using System.Collections;
using System.Transactions;
namespace EF.Demo
{
    class Program
    {
        static void Main(string[] args)
        {
            BlogCategory cate = null;
            DemoDBEntities context = new DemoDBEntities();

            //DemoDBEntities context2 = new DemoDBEntities();
            try
            {
                //using (TransactionScope scope = new TransactionScope())
                //{
                    //context.Configuration.LazyLoadingEnabled = false;
                    DbSet<BlogCategory> set = context.Set<BlogCategory>();

                    cate = new BlogCategory();
                    cate.CateName = "2010-7";
                    cate.CreateTime = DateTime.Now;

                    cate.BlogArticle.Add(new BlogArticle() { Title = "2011-7-15" });
                    set.Add(cate);

                    //由于没设置Title字段,并且CreateTime字段不能为空,故会引发异常
                    context.Set<BlogArticle>().Add(new BlogArticle { BlogCategory_CateID = 2 });
                    int a = context.SaveChanges();

                //    context2.Set().Add(new BlogArticle { BlogCategory_CateID = 2 });
                //    int b = context2.SaveChanges();

                //    scope.Complete();
                //}
            }
            catch(Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
            

            Console.ReadLine();           
        }
    }    
}

通过SQL SERVER Profile 监视到没有一句SQL语句被执行,SaveChanges事务是预执新所有操作成功后才会更新到数据库中。

我们再来测试一下分布式事务,创建的Context2用于模拟代表其它数据库


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using EF.Model;
using EF.DAL;
using System.Data.Entity;
using System.Collections;
using System.Transactions;
namespace EF.Demo
{
    class Program
    {
        static void Main(string[] args)
        {
            BlogCategory cate = null;
            DemoDBEntities context = new DemoDBEntities();

            DemoDBEntities context2 = new DemoDBEntities();
            try
            {
                using (TransactionScope scope = new TransactionScope())
                {
                    //context.Configuration.LazyLoadingEnabled = false;
                    DbSet<BlogCategory> set = context.Set<BlogCategory>();

                    cate = new BlogCategory();
                    cate.CateName = "2010-7";
                    cate.CreateTime = DateTime.Now;

                    cate.BlogArticle.Add(new BlogArticle() { Title = "2011-7-15" });
                    set.Add(cate);
                    //实例1 对数据库执行提交
                    int a = context.SaveChanges();

                    //实例2 模拟其它数据库提交 时间字段为空,无法更新成功
                    context2.Set<BlogArticle>().Add(new BlogArticle { Title="2011-7-16", BlogCategory_CateID = 2 });
                    int b = context2.SaveChanges();

                    scope.Complete();
                }
            }
            catch(Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
            

            Console.ReadLine();           
        }
    }    
}

通过SQL SERVER Profile 监视,虽然context实际执行了两条SQL记录,但是context2的SQL没有执行成功,导致事务回滚,所有操作都被没有执行成功。

你可能感兴趣的:(EF 自带事务)