.net core 事务

.net core 中的 事务 有三种 ef 中 的 SaveChanges , Database.BeginTransaction ,new TransactionScope

1 ef SaveChanges 事务 对DBContext 所有跟踪的实体变化做 原子性提交

例如 如下 配置 Name 最大长度为2 大于2 不能添加修改

    public class StudentConfig : IEntityTypeConfiguration<Student>
    {
        public void Configure(EntityTypeBuilder<Student> builder)
        {
            builder.ToTable("Students");
            builder.HasKey(x => x.Id);
            builder.Property(x => x.Name).HasMaxLength(2);
        }
    }

 

 string mysqlCon = "server=192.168.0.168;port=3306;database=UserDDD;pwd=123456;uid=root;";

  

            AppliactionContext appliactionContext = new AppliactionContext(
            new DbContextOptionsBuilder<AppliactionContext>()
            .UseMySql(mysqlCon, new MySqlServerVersion(new Version(8, 0, 27))).Options);
            appliactionContext.Students.Add(new Student("小"));
            appliactionContext.Students.Add(new Student("小明明"));
            appliactionContext.SaveChanges();

  

其中 第一条数据 符合 小于长度2 要求 第二条数据不符合 既然事务具有原子性 那么 SaveChanges 时候 两条都应该保存失败

 报异常了 数据库没有增加新数据

2 Database.BeginTransaction 

如果ef 操作有sql语句式的操作 如何使用事务 这个时候 需要 用 Database.BeginTransaction 

  AppliactionContext appliactionContext = new AppliactionContext(
  new DbContextOptionsBuilder<AppliactionContext>()
  .UseMySql(mysqlCon, new MySqlServerVersion(new Version(8, 0, 27))).Options);
  using (IDbContextTransaction trans = appliactionContext.Database.BeginTransaction())
  {
      try
      {
          appliactionContext.Students.Add(new Student("小"));
          // appliactionContext.Students.Add(new Student("小明明"));
          appliactionContext.Database.ExecuteSql($"insert Students(Name)VALUES({"小明明"})");
          appliactionContext.SaveChanges();
          trans.Commit();
      }
      catch (Exception ex)
      {
          trans.Rollback();
          throw ex;
      }
  }

  这里 执行到sql 语句的时候已经抛异常了 没到这里 appliactionContext.SaveChanges(); 就到catch 了 大致思路式这样的

 

3 Database.BeginTransaction 多个上下文 同一个数据库 共享一个事务 使用 Database.UseTransaction

使用 关联 事务 切记 需要要共享 DbConnection dbConnection = appliactionContext.Database.GetDbConnection()

下面代码 很简单 两个DBConext 关联同一个事务 

  string sqlCon = "Server=localhost;Database=UserDDD;Integrated Security=True;Encrypt=True;TrustServerCertificate=True";
  string mysqlCon = "server=192.168.0.168;port=3306;database=UserDDD;pwd=123456;uid=root;";
  //将连接拿出来,传到多个上下文中,这样是共享同一个连接
  AppliactionContext appliactionContext = new AppliactionContext(
  new DbContextOptionsBuilder<AppliactionContext>()
  .UseMySql(mysqlCon, new MySqlServerVersion(new Version(8, 0, 27))).Options);

  DbConnection dbConnection = appliactionContext.Database.GetDbConnection();
  IntegrationEventLogContext eventLogContext = new IntegrationEventLogContext(
  new DbContextOptionsBuilder<IntegrationEventLogContext>()
  .UseMySql(dbConnection, new MySqlServerVersion(new Version(8, 0, 27))).Options);

  using (var transaction = appliactionContext.Database.BeginTransaction())
  {
      try
      {
          eventLogContext.IntegrationEventLogs.Add(
              new IntegrationEventLogEntry(new EventBus.Events.IntegrationEvent(), Guid.NewGuid()));
          //关联当前事务
          eventLogContext.Database.UseTransaction(transaction.GetDbTransaction(), transaction.TransactionId);
          eventLogContext.SaveChanges();
          //添加学生
          appliactionContext.Students.Add(new Student("小") { Id = 199 });
          appliactionContext.SaveChanges();
          transaction.Commit();
      }
      catch (Exception ex)
      {
          transaction.Rollback();
          throw ex;
      }
  }

  

4 new TransactionScope() 

          using (TransactionScope transactionScope = new TransactionScope())
          {

          }

  

参考 :标红的重点看

  1. 事务 - EF Core | Microsoft Learn
  2. 分布式:分布式事务(CAP、两阶段提交、三阶段提交) - 知乎 (zhihu.com)
  3. 第五节:EF Core中的三类事务(SaveChanges、DbContextTransaction、TransactionScope) - 勇气可嘉 - 博客园 (cnblogs.com) 
  4. .net6中嵌套事务对象TransactionScope用法及释疑 - lanedm - 博客园 (cnblogs.com)
  5.  efcore事务使用 - .net&new - 博客园 (cnblogs.com)

posted on 2024-04-15 17:47  是水饺不是水饺  阅读(38)  评论(0)    收藏  举报

导航