事务(进程 ID 58)在锁资源上与另一个进程发生死锁,并已被选为死锁受害者。重新运行交易

问题描述 投票:0回答:1

我有一个 Blazor Wasm 应用程序,当我调用端点从数据库中获取卷记录列表时,会生成错误:事务(进程 ID 58)在锁资源上与另一个进程发生死锁,并已被选为死锁受害者。重新运行事务。老实说,我从来没有发生过这个错误,所以我不知道它发生的原因。以前,我的 httpget 端点工作正常。我唯一的结论是,它的发生是因为当从实体框架到数据库sql数据进行select查询时,同时我正在用hangfire执行计划任务,而计划任务指向的是volumetric表,即我的端点指向选择查询的端点相同,正是在那一刻,错误一定会发生。

这是我生成错误的代码:

 [HttpGet]
 public async Task<ActionResult<NIAResponse<ResponsePaged<VolumetricRecord>>>> Get(
                                                    [FromQuery] int Page = 1,
                                                    [FromQuery] int PageSize = 10,
                                                    [FromQuery] string Filters = null,
                                                    [FromQuery] string Sorts = null,
                                                    [FromQuery] bool AllItems = false,
                                                    [FromQuery] string Culture = "en",
                                                    [FromQuery] long IdTypeOperation = 1,
                                                    [FromQuery] long IdInstallation = 0,
                                                    [FromQuery] long IdEquipment = 0,
                                                    [FromQuery] long IdProduct = 0,
                                                    [FromQuery] long IdMeasure = 0,
                                                    [FromQuery] long IdInformationType = 0,
                                                    [FromQuery] string? strDateSearch = "",
                                                    [FromQuery] string? strDateEndSearch = "")
 {
     try
     {
         var DateSearch = new DateTime();
         DateSearch = new DateTime(int.Parse(strDateSearch.Split("-")[0]), int.Parse(strDateSearch.Split("-")[1]), int.Parse(strDateSearch.Split("-")[2]));

         var DateEndSearch = new DateTime();
         DateEndSearch = new DateTime(int.Parse(strDateEndSearch.Split("-")[0]), int.Parse(strDateEndSearch.Split("-")[1]), int.Parse(strDateEndSearch.Split("-")[2]));

         var queriable = _context.VolumetricRecords
             .Include(x => x.Equipment).ThenInclude(x => x.Product).ThenInclude(x => x.ProductCatalog)
             .Include(x => x.Equipment).ThenInclude(x => x.Product).ThenInclude(x => x.SubProductCatalog)
             .Include(x => x.Equipment).ThenInclude(x => x.Product).ThenInclude(x => x.UnitOfMeasurementCatalog)
             .Include(x => x.Equipment).ThenInclude(x => x.Level).ThenInclude(x => x.Permission)
             .Include(x => x.Measure)
             .Include(x => x.Hose)
             .Include(x=> x.TaxOperation)
             .Where(x=>x.Status == true)
             .Where(x => x.VolumetricStartDate.Date >= DateSearch.Date && x.VolumetricStartDate.Date <= DateEndSearch.Date)
             .OrderBy(x => x.VolumetricStartDate)//RowNumber
             .ThenBy(x => x.RowNumber)
             .AsQueryable();

         queriable = Filter(queriable, Filters, Culture);
         queriable = Sort(queriable, Sorts);

         ResponsePaged<VolumetricRecord> objResponse = new ResponsePaged<VolumetricRecord>();
         var data = await queriable.ToListAsync();
         var receipFinales = data;

         if (IdInstallation > 0)
         {
             receipFinales = receipFinales.Where(x => x.Equipment.LevelId == IdInstallation).ToList();
         }

         if (IdProduct > 0)
         {
             receipFinales = receipFinales.Where(x => x.Equipment.Product.Id == IdProduct).ToList();
         }

         if (IdEquipment > 0)
         {
             receipFinales = receipFinales.Where(x => x.Equipment.Id == IdEquipment).ToList();
         }

         if (IdMeasure > 0)
         {
             receipFinales = receipFinales.Where(x => x.IdMeasure == IdMeasure).ToList();
         }

         if (IdInformationType == (int)TypeOfInformationVolumetric.Todos)
         {
             if (IdTypeOperation == 1) //Recepcion
             {
                 receipFinales = receipFinales.Where(x => (x.TypeOfVolumetricRecord == TypeOfVolumetricRecord.Recepcion_Manual || x.TypeOfVolumetricRecord == TypeOfVolumetricRecord.Recepcion)).ToList();
             }
             else
             {
                 receipFinales = receipFinales.Where(x => (x.TypeOfVolumetricRecord == TypeOfVolumetricRecord.Entrega_Manual || x.TypeOfVolumetricRecord == TypeOfVolumetricRecord.Entrega)).ToList();
             }
         }
         else if (IdInformationType == (int)TypeOfInformationVolumetric.Automatico)
         {
             if (IdTypeOperation == 1) //Recepcion
             {
                 receipFinales = receipFinales.Where(x => (x.TypeOfVolumetricRecord == TypeOfVolumetricRecord.Recepcion)).ToList();
             }
             else
             {
                 receipFinales = receipFinales.Where(x => (x.TypeOfVolumetricRecord == TypeOfVolumetricRecord.Entrega)).ToList();
             }
         }
         else if (IdInformationType == (int)TypeOfInformationVolumetric.Manual)
         {
             if (IdTypeOperation == 1) //Recepcion
             {
                 receipFinales = receipFinales.Where(x => (x.TypeOfVolumetricRecord == TypeOfVolumetricRecord.Recepcion_Manual)).ToList();
             }
             else
             {
                 receipFinales = receipFinales.Where(x => (x.TypeOfVolumetricRecord == TypeOfVolumetricRecord.Entrega_Manual)).ToList();
             }
         }

         TypeofEquipment firstEquipmentType = receipFinales.Select(receipt => receipt.Equipment.TypeofEquipment).FirstOrDefault();

         if (firstEquipmentType == TypeofEquipment.Dispensario)
         {
             AcumuladosTotalizadores total = new AcumuladosTotalizadores();
             total.Volume = receipFinales.Sum(item => item.VolumenEntregadoTotalizadorInstantaneo) ?? 0.0m;            
             objResponse.Totes = total;                   
         }
         else
         {
             AcumuladosTotalizadores total = new AcumuladosTotalizadores();
             total.Volume = receipFinales.Sum(item => item.VolumetricVolume) ?? 0.0m;
             objResponse.Totes = total;                    
         }

         objResponse.TotalItemCount = receipFinales.Count();

         if (!AllItems)//Cuando solicita todos los datos (se usa para exportar todos los datos a excel)
         {
             Page = Page <= 0 ? 1 : Page;
             if (objResponse.TotalItemCount > PageSize)
                 receipFinales = receipFinales.Skip(PageSize * (Page - 1)).Take(PageSize).ToList();
         }

         objResponse.CurrentPageData = receipFinales;               

         var log = new BasicActionLog
         {
             IP_Address = getIpMac.GetIp().ToString(),
             Mac_Address = getIpMac.GetMac().ToString(),
             Action = TypeActionLog.Read.ToString(),
             Description = "",
             LogType = (int)ELogType.Operaciones_cotidianas,                   
             Component = "Registros volumetricos"
         };
         await actionLogServices.AddActionLog(log, true);

         var logsec = new BasicActionLog
         {
             IP_Address = getIpMac.GetIp().ToString(),
             Mac_Address = getIpMac.GetMac().ToString(),
             Action = TypeActionLog.Read.ToString(),
             Description = "",
             LogType = (int)ELogType.Registro_de_actividad_de_los_usuarios,
             Is_Security = true,
             Component = "Registros volumetricos"
         };
         await actionLogServices.AddActionLog(logsec, true);

         return new NIAResponse<ResponsePaged<VolumetricRecord>>
         {
             Code = 200,
             Success = true,
             Obj = objResponse,
         };
     }
     catch (Exception e)
     {
         var log = new BasicActionLog
         {
             IP_Address = getIpMac.GetIp().ToString(),
             Mac_Address = getIpMac.GetMac().ToString(),
             Action = TypeActionLog.Read.ToString(),
             Description = e.Message,
             Is_Security = true,
             LogType = (int)ELogType.Errores_y_excepciones_en_la_operacion_del_programa,
             Component = "Registros volumetricos"
         };
         await actionLogServices.AddActionLog(log, true);

         return new NIAResponse<ResponsePaged<VolumetricRecord>>
         {
             Code = e.GetHashCode(),
             Message = e.Message,
             Success = false,
         };
     }
 }
c# sql-server entity-framework-core hangfire
1个回答
0
投票

涉及只读事务的死锁最可能的原因是您没有在 SNAPSHOT 隔离中运行或使用 READ COMMITTED SNAPSHOT 数据库选项。您可以在here阅读有关它们的信息,但总结是,通过行版本控制,您不需要 SELECT 查询的任何锁,因此不可能出现死锁。

© www.soinside.com 2019 - 2024. All rights reserved.