2

我将MySQLEF Core一起使用。我目前正在使用Pomelo Provider for MySQL。我需要为事务实施工作单元模式。我有一个服务,它调用存储库中的两种方法。我无法实现嵌套事务。这就是我的服务方法现在的样子:

    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();
            }
        }
     }

任何人都可以帮助我吗?

4

0 回答 0