• 【EF Core】三种事务(SaveChange、DBContextTransaction、TransactionScope)


    EF中的事务主要分为三类,分别是SaveChangesDbContextTransactionTransactionScope

    SaveChanges

    SaveChanges一次性将本地缓存中所有的状态变化一次性提交到数据库,这就是一个事务,要么统一成功,要么统一回滚。
    使用场景:一个DBContext,即一个数据库的EF的上下文,不能控制多个数据库。

    DbContextTransaction事务

    通常用于手动接管事务,某些操作是一个事务,某些操作是另外一个事务。
    使用场景:EF调用SQL语句的时候使用该事务、 多个SaveChanges;不同控制多个数据库

    private static void TestDbContextTransactionFailure()
    {
        using (DbContext db = new CodeFirstModel())
        {
            DbContextTransaction trans = null;
            try
            {
                //开启事务
                trans = db.Database.BeginTransaction();
                //增加
                string sql1 = @"insert into TestInfor  values(@id,@txt1,@txt2)";
                SqlParameter[] pars1 ={
                                             new SqlParameter("@id",Guid.NewGuid().ToString("N")),
                                             new SqlParameter("@txt1","txt11"),
                                             new SqlParameter("@txt2","txt22")
                                        };
                db.Database.ExecuteSqlCommand(sql1, pars1);
                //修改
                string sql3 = @"update TestInfor set txt1=@txt1 where id=@id";
                SqlParameter[] pars3 ={
                                             new SqlParameter("@id","3"),
                                             new SqlParameter("@txt1","二狗子222")
                                        };
                db.Database.ExecuteSqlCommand(sql3, pars3);
    
                //提交事务
                trans.Commit();
                Console.WriteLine("事务成功了");
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
                trans.Rollback();
    
            }
            finally
            {
                trans.Dispose();
            }
        }
    }
    

    TransactionScope事务

    该事务用来处理多个SaveChanges的事务(特殊情况的业务)或者多个DBContext(每个DBContext是一个实例,代表不同的数据库连接).
    如果使用该事务来处理多个数据库(多个DBContex)时,必须手动开启msdtc服务,这样才可以将多个DB的SaveChange给放到一个事务中
    使用场景:

    • 多数据库连接的情况
    • 主键id自增的情况,同一个业务线中,需要拿到新增加的数据的主键id,进行操作。

    主键自增被使用的情况的解决方案

    private static void Test3()
            {
                using (DbContext db = new CodeFirstModel())
                {
                    using (TransactionScope trans = new TransactionScope())
                    {
                        try
                        {
                            TestInfor2 t1 = new TestInfor2()
                            {
                                txt11 = Guid.NewGuid().ToString("N"),
                                txt22 = Guid.NewGuid().ToString("N")
                            };
                            db.Set<TestInfor2>().Add(t1);
                            //如果这里不写SaveChanges的话,t1.id永远为0
                            db.SaveChanges();
    
    
                            TestInfor2 t2 = new TestInfor2()
                            {
                                txt11 = (t1.id + 1).ToString(),
                                txt22 = Guid.NewGuid().ToString("N")
                            };
                            db.Entry(t2).State = EntityState.Added;
                            db.SaveChanges();
    
                            //事务统一提交(若失败则统一回滚)
                            trans.Complete();
                            Console.WriteLine("自增提交成功");
                        }
                        catch (Exception)
                        {
                            Transaction.Current.Rollback();
                        }
                    }
                }
            }
    

    多个DBContext、多个数据库的情况。

    private static void TransactionScopeTwoDB()
            {
                using (TransactionScope trans = new TransactionScope())
                {
                    try
                    {
                        DbContext db1 = new CodeFirstModel();
                        DbContext db2 = new CodeFirstModel2();
                        //数据库1
                        TestInfor t1 = new TestInfor()
                        {
                            id = Guid.NewGuid().ToString("N"),
                            txt1 = "111111111",
                            txt2 = "222222222222"
                        };
                        db1.Entry(t1).State = EntityState.Added;
                        db1.SaveChanges();
    
                        //数据库2
                        TestOne t2 = new TestOne()
                        {
                            id = Guid.NewGuid().ToString("N"),    //可以在此处手动制造个错误,来测试多数据库的回滚问题
                            t1 = "222",
                            t2 = "2222"
                        };
                        db2.Entry(t2).State = EntityState.Added;
                        db2.SaveChanges();
    
                        trans.Complete();
                        Console.WriteLine("多个数据库添加成功");
                    }
                    catch (Exception)
                    {
                        Transaction.Current.Rollback();
                    }
    
                }
            }
    
  • 相关阅读:
    如何编写一个简单的依赖注入容器
    网站框架的动态编译的实现原理
    Python实现语音识别和语音合成
    OpenCV图像处理以及人脸识别
    Shell教程快速入门
    TensorFlow入门教程
    如何免费使用Google的GPU跑深度学习代码
    高等数学系列文章
    Git系列教程
    一键构造你的博客园目录
  • 原文地址:https://www.cnblogs.com/fanfan-90/p/16296737.html
Copyright © 2020-2023  润新知