Entity Framework中的SqlException - 因为会话中有其他线程正在运行,所以不允许新的事务。

679

我目前遇到了这个错误:

System.Data.SqlClient.SqlException:因为会话中有其他线程在运行,所以不允许新事务。

在运行以下代码时出现此错误:

public class ProductManager : IProductManager
{
    #region Declare Models
    private RivWorks.Model.Negotiation.RIV_Entities _dbRiv = RivWorks.Model.Stores.RivEntities(AppSettings.RivWorkEntities_connString);
    private RivWorks.Model.NegotiationAutos.RivFeedsEntities _dbFeed = RivWorks.Model.Stores.FeedEntities(AppSettings.FeedAutosEntities_connString);
    #endregion

    public IProduct GetProductById(Guid productId)
    {
        // Do a quick sync of the feeds...
        SyncFeeds();
        ...
        // get a product...
        ...
        return product;
    }

    private void SyncFeeds()
    {
        bool found = false;
        string feedSource = "AUTO";
        switch (feedSource) // companyFeedDetail.FeedSourceTable.ToUpper())
        {
            case "AUTO":
                var clientList = from a in _dbFeed.Client.Include("Auto") select a;
                foreach (RivWorks.Model.NegotiationAutos.Client client in clientList)
                {
                    var companyFeedDetailList = from a in _dbRiv.AutoNegotiationDetails where a.ClientID == client.ClientID select a;
                    foreach (RivWorks.Model.Negotiation.AutoNegotiationDetails companyFeedDetail in companyFeedDetailList)
                    {
                        if (companyFeedDetail.FeedSourceTable.ToUpper() == "AUTO")
                        {
                            var company = (from a in _dbRiv.Company.Include("Product") where a.CompanyId == companyFeedDetail.CompanyId select a).First();
                            foreach (RivWorks.Model.NegotiationAutos.Auto sourceProduct in client.Auto)
                            {
                                foreach (RivWorks.Model.Negotiation.Product targetProduct in company.Product)
                                {
                                    if (targetProduct.alternateProductID == sourceProduct.AutoID)
                                    {
                                        found = true;
                                        break;
                                    }
                                }
                                if (!found)
                                {
                                    var newProduct = new RivWorks.Model.Negotiation.Product();
                                    newProduct.alternateProductID = sourceProduct.AutoID;
                                    newProduct.isFromFeed = true;
                                    newProduct.isDeleted = false;
                                    newProduct.SKU = sourceProduct.StockNumber;
                                    company.Product.Add(newProduct);
                                }
                            }
                            _dbRiv.SaveChanges();  // ### THIS BREAKS ### //
                        }
                    }
                }
                break;
        }
    }
}

模型#1 - 此模型位于我们的 Dev 服务器上的数据库中。 模型#1 http://content.screencast.com/users/Keith.Barrows/folders/Jing/media/bdb2b000-6e60-4af0-a7a1-2bb6b05d8bc1/Model1.png

模型#2 - 此模型位于我们的 Prod 服务器上的数据库中,并且每天通过自动供应更新。 alt text http://content.screencast.com/users/Keith.Barrows/folders/Jing/media/4260259f-bce6-43d5-9d2a-017bd9a980d4/Model2.png

注意 - 模型#1 中用红圈标出的项目是我用来“映射”到模型#2 的字段。 请忽略模型#2 中的红色圆圈:那是我曾经提出的另一个问题,现在已得到解答。

注意:我仍然需要进行 isDeleted 检查,以便如果已经从客户的清单中删除,则可以从 DB1 中进行软删除。

我想要做的所有事情,就是使用此特定代码将 DB1 中的公司与 DB2 中的客户连接起来,从 DB2 获取其产品清单,如果它们还不存在于 DB1 中,则将其插入到 DB1 中。 第一次运行应该是完全提取库存。 之后每次运行都不应发生任何事情,除非新的库存在夜间供应中出现。

  

那么最重要的问题是 - 我如何解决我正在遇到的事务错误? 我需要在循环中每次放弃并重新创建我的上下文吗(这对我来说没有意义)?


8
这是我见过的最详细的问题。 - user220583
14
有人还想念存储过程吗? - David
23个回答

0

我来晚了,但今天我遇到了同样的错误,解决方法很简单。我的情况类似于给定代码,我在嵌套的 for-each 循环中进行 DB 事务。

问题是单个 DB 事务所需的时间比 for-each 循环长一点,因此一旦早期事务未完成,新的事务就会抛出异常,因此解决方案是在您进行 db 事务的 for-each 循环中创建一个新对象。

对于上述情况,解决方案如下:

foreach (RivWorks.Model.Negotiation.AutoNegotiationDetails companyFeedDetail in companyFeedDetailList)
                {
private RivWorks.Model.Negotiation.RIV_Entities _dbRiv = RivWorks.Model.Stores.RivEntities(AppSettings.RivWorkEntities_connString);
                    if (companyFeedDetail.FeedSourceTable.ToUpper() == "AUTO")
                    {
                        var company = (from a in _dbRiv.Company.Include("Product") where a.CompanyId == companyFeedDetail.CompanyId select a).First();
                        foreach (RivWorks.Model.NegotiationAutos.Auto sourceProduct in client.Auto)
                        {
                            foreach (RivWorks.Model.Negotiation.Product targetProduct in company.Product)
                            {
                                if (targetProduct.alternateProductID == sourceProduct.AutoID)
                                {
                                    found = true;
                                    break;
                                }
                            }
                            if (!found)
                            {
                                var newProduct = new RivWorks.Model.Negotiation.Product();
                                newProduct.alternateProductID = sourceProduct.AutoID;
                                newProduct.isFromFeed = true;
                                newProduct.isDeleted = false;
                                newProduct.SKU = sourceProduct.StockNumber;
                                company.Product.Add(newProduct);
                            }
                        }
                        _dbRiv.SaveChanges();  // ### THIS BREAKS ### //
                    }
                }

0

我有点晚了,但我也遇到了这个错误。通过检查正在更新的值,我解决了这个问题。

我发现我的查询语句是错误的,并且有超过250个待处理的编辑。所以我纠正了我的查询语句,现在它可以正确地工作了。

所以在我的情况下:通过调试查询返回的结果来检查错误的查询。之后纠正查询语句。

希望这可以帮助解决未来的问题。


-1

大多数与循环有关的答案。但我的问题不同。当我尝试在同一范围内使用多个dbcontext.Savechanges()命令时,我多次遇到错误。

在我的情况下,对于ef core 3.1使用

dbcontext.Database.BeginTransaction() and dbcontext.Database.CommitTransaction();

问题已经被修复。这是我整个的代码:

 public IActionResult ApplyForCourse()
    {

        var master = _userService.GetMasterFromCurrentUser();

            var trainee = new Trainee
            {
                CourseId = courseId,
                JobStatus = model.JobStatus,
                Gender = model.Gender,
                Name = model.Name,
                Surname = model.Surname,
                Telephone = model.Telephone,
                Email = model.Email,
                BirthDate = model.BirthDate,
                Description = model.Description,
                EducationStatus = EducationStatus.AppliedForEducation,
                TraineeType = TraineeType.SiteFirst

            };


            dbcontext.Trainees.Add(trainee);
            dbcontext.SaveChanges();

         
            dbcontext.Database.BeginTransaction();
            var user = userManager.GetUserAsync(User).Result;
            master.TraineeId = trainee.Id;
            master.DateOfBirth = model.BirthDate;
            master.EducationStatus = trainee.EducationStatus;
            user.Gender = model.Gender;
            user.Email = model.Email;
            dbcontext.Database.CommitTransaction();
            dbcontext.SaveChanges();
 
            return RedirectToAction("Index", "Home");

        }


    }

不成立。如果不允许进行新的交易(这就是问题所在),为什么当你试图显式地启动它时,它会神奇地被允许呢? - Gert Arnold
亲爱的阿诺德,我不知道为什么你不喜欢我的评论。我只是遇到了同样的错误,在尝试了几次之后,它对我起作用了,也许对其他人有帮助。如果你想确定,你可以试试,但在不知道它是否有效之前,你不应该不喜欢一个评论。 - ahmetsokmen
这不是关于喜欢或不喜欢的问题。我喜欢人们尝试为Stack Overflow做出贡献,但这只与内容有关。如果您发布的代码对外行人毫无意义,那就没有意义了。首先,不清楚为什么会抛出异常,更不用说为什么被修复了。作为一般准则,在回答问题时应使用问题中提供的代码。 - Gert Arnold
这并没有真正回答问题。如果您有不同的问题,可以通过点击提问来提出。如果您想在此问题获得新的答案时得到通知,您可以关注此问题。一旦您拥有足够的声望,您还可以添加悬赏以吸引更多关注。- 来自审核 - Chris Warrick

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接