【问题标题】:LINQ to Entities Transaction Performance IssueLINQ to Entity 事务性能问题
【发布时间】:2016-04-17 04:40:49
【问题描述】:
public void Register(decimal groupId, decimal deptId, decimal employeeId)
{
    using (EmployeeEntities db = new EmployeeEntities())
    {
       using (TransactionScope scope = new TransactionScope(TransactionScopeOption.Required, new TransactionOptions { IsolationLevel = IsolationLevel.Snapshot }))
       {
          var course = db.Courses.Where(s => s.GroupId == groupId && s.DepartmentId == deptId).ToList();                  

          foreach (var item in course)
          {
             var filledSeats = db.CourseRegistrations.Count(c => c.CourseId == item.CourseId && c.DepartmentId == deptId && (c.CancelledFl == null || c.CancelledFl == false));

             if (item.AllotedSeats <= filledSeats)
             {
                throw new Exception("Sorry! Seats are not available for " + db.Groups.Where(s => s.GroupId == item.GroupId).Select(s => s.GroupName).FirstOrDefault());
             }
             if (!db.CourseRegistrations.Any(s => s.EmployeeId == employeeId && s.CourseId == item.CourseId && (s.CancelledFl == false || s.CancelledFl == null)))
             {
                 var courseRegister = new CourseRegistration();
                 db.CourseRegistrations.Add(courseRegister);
                 courseRegister.CourseId = item.CourseId;
                 courseRegister.EmployeeId = employeeId;
                 courseRegister.CreatedBy = 1;
                 courseRegister.CreatedDt = DateTime.Now;
                 courseRegister.RecordVa = 1;

                 item.FilledSeats = item.FilledSeats + 1;
             }
          }
          db.SaveChanges();
          scope.Complete();
       }    
    }  
}

考虑上面的代码。当请求发送到ASP.NET WebAPI 控制器时,它最终会被调用。

该功能只是在检查座位可用性后将员工注册到课程。大约 200 名员工将同时注册课程。

我在每笔交易中都使用Snapshot Isolation

我的问题在于性能。这是。有时会超时。

我的问题是为什么?我的代码的哪一部分出错了?所有这些交易中到底发生了什么?什么等待或什么锁定?

【问题讨论】:

    标签: c# sql-server performance entity-framework asp.net-web-api


    【解决方案1】:

    您在 for 循环中对数据库进行了多次调用,这意味着您消耗 db 请求延迟的总成本 2 x course.length 次,而您应该只需要吃一次,也许两次。看看您是否可以将来自db.CourseRegistrations 的必要数据带出循环,可能作为与来自 Courses 的数据连接的同一查询的一部分。然后你可以在内存中做循环内的操作,速度会快几个数量级。

    【讨论】:

      【解决方案2】:

      如果您正在执行许多更新/插入,默认情况下 EF 会自动跟踪这些更改,如果您要更新许多记录,这会真正影响性能。为了解决这个问题,您可以在进行批量更新之前关闭AutoDetectChangesEnabled 功能,然后在完成后立即重新开启;

              try
              {
                  db.Configuration.AutoDetectChangesEnabled = false;
                  //loop through your updates here
              }
              finally
              {
                  db.Configuration.AutoDetectChangesEnabled = true;
              }
      
              db.SaveChanges();
      

      【讨论】:

        猜你喜欢
        • 2011-06-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-01-06
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多