You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

EF Core并行更新事务无异常但数据未更新,求排查方案

问题

我是Entity Framework Core新手,需要批量更新多个产品的若干字段(详见代码中的updateFieldList变量),且每个更新必须通过ExecuteSqlRawAsync调用存储过程生成变更日志(ERP系统强制要求)。单线程运行时代码正常,但533个产品要耗时约5分钟,所以尝试用Tasks并行优化。我知道多任务不能共用同一个DbContext,参考官方文档写了下面的代码,但现在代码无异常但数据完全没更新,求排查方向。

public async Task<Result> UpdateProductStatus(List<DTO.QueryResult> productsUpdateList, Vorlauf newProductStatus, string changeReason)
{
    try
    {
        var updateFieldList = new List<FieldUpdate>()
        {
            new FieldUpdate("Prodstat", newProductStatus.Nummer),
            new FieldUpdate("_Date", DateTime.Now),
            new FieldUpdate("_User", Environment.UserName)
        };
        if(changeReason.Trim() != string.Empty)
        {
            updateFieldList.Add(new FieldUpdate("Stchinfo", changeReason));
        }
        if (newProductStatus.Log5 == 1)
        {
            updateFieldList.Add(new FieldUpdate("Sperr", (byte)1));
        }
        using var connection = new SqlConnection(Connection.GetImpGgConnectionString());
        var options = new DbContextOptionsBuilder<IMP_GG_Context>()
            .UseSqlServer(connection)
            .Options;
        using var context1 = new IMP_GG_Context(connection);
        using (var transaction = context1.Database.BeginTransaction())
        {
            var predicate = PredicateBuilder.New<Artikel>();
            foreach (var product in productsUpdateList)
            {
                predicate = predicate.Or(artikel => artikel._Kenn == product.ProductId);
            }
            var products = context1.ArtikelTable.Where(predicate).ToList();
            List<Task> tasks = new List<Task>();
            foreach (var product in products)
            {
                var task = Task.Run(() =>
                {
                    using(var context2 = new IMP_GG_Context(connection))
                    {
                        context2.Database.UseTransaction(transaction.GetDbTransaction());
                        foreach (FieldUpdate fieldUpdate in updateFieldList)
                        {
                            var updateResult = UpdateArtikel(product, fieldUpdate);
                            Changelog changelog = new Changelog(product, fieldUpdate.DatabaseFieldName.ToUpper(), fieldUpdate.OldValue.ToString(), fieldUpdate.NewValue.ToString());
                            string changeLogQuery = changelog.CreateQuery;
                            var parameters = changelog.GetSqlParameterList();
                            var result = _Context.Database.ExecuteSqlRawAsync(changeLogQuery, parameters);
                            context2.SaveChanges();
                        }
                    }
                });
                tasks.Add(task);
            }
            Task.WaitAll(tasks.ToArray());
            transaction.Commit();
            return new Result(Enums.ResultStatus.Success);
        }
    }
    catch(Exception exception)
    {
        return new Result(Enums.ResultStatus.Failure, exception.Message + Environment.NewLine + exception.StackTrace);
    }
}
排查方向
  • 实体跟踪问题:任务中使用的product是context1查询出的跟踪实体,context2并未附加该实体,导致SaveChanges()无更新操作。需在context2中重新查询产品,或调用context2.ArtikelTable.Attach(product)并标记实体为修改状态(如context2.Entry(product).State = EntityState.Modified;)。
  • 异步操作未等待:调用ExecuteSqlRawAsync时未加await,会导致存储过程还未执行就执行SaveChanges(),甚至任务结束后操作才完成。必须添加await等待异步调用完成。
  • 上下文与连接的状态问题:创建context2时,需确保共享的数据库连接处于打开状态。可在context1启动事务前手动打开连接:await context1.Database.OpenConnectionAsync();。
  • 事务共享有效性:检查context2.Database.UseTransaction(transaction.GetDbTransaction())是否正确绑定了事务,确认事务对象未失效,且上下文的数据库提供程序与事务匹配。
  • UpdateArtikel方法逻辑:验证该方法是否正确修改了product的目标字段。若字段未被实际修改,即使上下文跟踪实体,也不会生成更新语句。可通过断点或日志查看修改后的实体字段值。
  • _Context的错误使用:任务中使用外部的_Context调用存储过程,未使用当前任务的context2,导致变更日志操作不在共享事务内,甚至引发多线程访问上下文的问题。需替换为context2.Database.ExecuteSqlRawAsync(...)。
  • 异常吞入问题:Task.Run内的异常可能未被外层try-catch捕获,导致隐性失败。建议将Task.WaitAll替换为await Task.WhenAll(tasks)(外层方法为async,应使用异步等待而非阻塞),并在任务内部添加try-catch捕获异常。

内容的提问来源于stack exchange,提问作者dns_nx

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 08:47:36