使用mysql和实体框架核心的嵌套事务

iyr7buue  于 2021-06-17  发布在  Mysql
关注(0)|答案(0)|浏览(365)

我正在使用mysql和ef-core。我目前正在使用pomeloproviderformysql。我需要为事务实现工作单元模式。我有一个服务调用存储库中的两个方法。我无法实现嵌套事务。我现在使用的方法是这样的:

public void methodA(param)
    {
      using (TransactionScope tx = new 
        TransactionScope(TransactionScopeOption.Required))
        {
          repo1.save(data1);
          repo2.save(data2);
          tx.complete();
        }
    }

这就是repo1中save方法的实现方式

private readonly UserDbContext appDbContext;
    public repo1(UserDbContext _appDbContext)
    {
        appDbContext = _appDbContext;
    }
    public void save(User entity)
    {
        var dbset = appDbContext.Set<User>().Add(entity);
        appDbContext.SaveChanges();
    }

这就是repo2中save方法的实现方式

private readonly UserDbContext appDbContext;
    public repo2(UserDbContext _appDbContext)
    {
        appDbContext = _appDbContext;
    }
    public void save(UserRole entity)
    {
        var dbset = appDbContext.Set<UserRole>().Add(entity);
        appDbContext.SaveChanges();
    }

在服务中运行方法时出现以下错误:
为警告“microsoft.entityframeworkcore.database.transaction.ambienttransactionwarning:检测到环境事务”生成错误。当前提供程序不支持环境事务。看到了吗http://go.microsoft.com/fwlink/?linkid=800142'. 通过将事件id“relationaleventid.ambienttransactionwarning”传递到“dbcontext.onconfiguring”或“adddbcontext”中的“configurewarnings”方法,可以抑制或记录此异常。
我就是这样在startup.cs中注册userdbcontext的

services.AddDbContext<UserDbContext>(options => options.UseLazyLoadingProxies().UseMySql("Server = xxxx; Database = xxx; Uid = xx;ConnectionReset=True;", b => b.MigrationsAssembly("AssemblyName")));

我甚至尝试添加一个中间件,在请求开始时启动事务,在响应期间提交/回滚。但我仍然无法管理嵌套事务。
我的中间件是这样的:

public class TransactionPerRequestMiddleware
    {
       private readonly RequestDelegate next_;

       public TransactionPerRequestMiddleware(RequestDelegate next)
        {
         next_ = next;
        }

       public async Task Invoke(HttpContext context, UserDbContext 
        userDbContext)
        {
           var transaction = userDbContext.Database.BeginTransaction(
           System.Data.IsolationLevel.ReadCommitted);

           await next_.Invoke(context);

           int statusCode = context.Response.StatusCode;
           if (statusCode == 200 || statusCode==302)
            {
            transaction.Commit();
            }
            else
            {
            transaction.Rollback();
            }
        }
     }

有人能帮我吗?

暂无答案!

目前还没有任何答案,快来回答吧!

相关问题