c# - 更新数据时出现 SQL 错误 - 事务(进程 ID)已死锁
问题描述
假设我的应用程序应该管理水果。我有一堆规则应该用来检测我的一种水果是否有问题。您可以在下面找到负责更新这些规则检测到错误的水果的类。
我的问题是,由于我已经并行化了这个过程,我随机得到这个错误:
事务(进程 ID)在锁定资源上与另一个进程死锁,并已被选为死锁牺牲品。
我不知道我的代码有什么问题。
你可以问我任何问题,我的英语不是很完美,我已经更改了一些 var 的名称(我的应用程序不管理水果)。
public class WrongFruitBus : GenericRepository<WrongFruit>, IWrongFruitBusiness, IBaseWrong
{
public WrongFruitBus() : base() { }
public WrongFruitBus(ILifetimeScope _Container) : base(_Container) { }
private readonly object currentProcessLock = new object();
public UpdateWrongFruits {
var CurrentProcessBus = new CurrentProcessBusiness();
var currentProcess = new CurrentProcess();
var FruitRulesBus = new FruitRulesBusiness(this.Container);
var FruitViewBus = new FruitViewBusiness();
var FruitRules = new List<FruitRule>();
FruitRules = FruitRulesBus.GetMany(x => x.ID == entity.RulesFilterId).ToList();
List<Task> allRules = new List<Task>();
foreach (var fruitRule in FruitRules)
{
Task task = Task.Factory.StartNew(() =>
{
using (ILifetimeScope tempContainer = this.Container.BeginLifetimeScope())
{
var tempWrongFruitBus = new WrongFruitBus(tempContainer);
//Get the request associate to the rule
var request = fruitRule.Request.JsonDeserialize<BaseFruitSearchSelectionModel>();
//Delete all existing detected fruits for this rule
tempWrongFruitBus.GetManyWithSelector(x => x.ID, x => x.RulesFilterId == fruitRule.ID).ToList().ForEach(x => tempWrongFruitBus.Delete(x));
var searchList = FruitSearchHelper.BuildSearchRequest(request);
var Ids = FruitViewBus.GetCustomList(null, null, searchList, null, null);
var RulesLists = Ids
.Results
.Cast<FruitResult>()
.Select(x =>
new WrongFruit()
{
FruitId = x.UId,
RulesFilterId = FruitRule.ID,
}).ToList();
RulesLists.ForEach(x => tempWrongFruitBus.Add(x));
tempWrongFruitBus._BusinessUnitOfWork.Commit();
//Update of the process progression
int PercentageAdvancement = 100 / NumberOfRules;
lock (currentProcessLock)
{
currentProcess = CurrentProcessBus.Get(x => x.TaskName == entity.TaskName);
currentProcess.TaskAdvancement = currentProcess.TaskAdvancement + PercentageAdvancement;
if (currentProcess.TaskAdvancement > 100)
{
currentProcess.TaskAdvancement = 100;
}
CurrentProcessBus.Update(currentProcess);
}
}
});
allRules.Add(task);
}
Task.WaitAll(allRules.ToArray());
}
}
服务器的日志文件
UncaGS.WCF.ErrorHandler.HandleError(:0) System.ServiceModel.Dispatcher.ChannelHandler.AsyncMessagePump > System.ServiceModel.Dispatcher.ChannelHandler.HandleRequest > System.ServiceModel.Dispatcher.ChannelHandler.DispatchAndReleasePump > System.ServiceModel.Dispatcher.MessageRpc.Process > System.ServiceModel.Dispatcher.MessageRpc.ProcessError > System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage8
System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage9 System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessageCleanup System.ServiceModel.Dispatcher.ErrorBehavior.HandleErrorCommon > UncaGS.WCF.ErrorHandler.HandleError System.Reflection.TargetInvocationException: Une exception a été levée par la cible d '不上诉。---> System.Data.Entity.Core.EntityCommandExecutionException:从商店提供者的数据读取器读取时出错。有关详细信息,请参阅内部异常。---> System.Data.SqlClient.SqlException:事务(进程 ID 57)与另一个进程在锁资源上死锁,并已被选为死锁受害者。à System.Data.SqlClient.SqlConnection.OnError(SqlException 异常, Boolean breakConnection, Action
1 wrapCloseInAction) à System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj, Boolean callerHasConnectionLock, Boolean asyncClose) à System.Data.SqlClient.TdsParser.TryRun(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj, Boolean& dataReady) à System.Data.SqlClient.SqlDataReader.TryHasMoreRows(Boolean& moreRows) à System.Data.SqlClient.SqlDataReader.TryReadInternal(Boolean setTimeout, Boolean& more) à System.Data.SqlClient.SqlDataReader.Read() à System.Data.Entity.Core.Common.Internal.Materialization.Shaper
1.StoreRead() --- Fin de la trace de la Pile d'exception interne --- à System.Data.Entity.Core.Common.Internal.Materialization.Shaper1.HandleReaderException(Exception e) à System.Data.Entity.Core.Common.Internal.Materialization.Shaper
1.StoreRead() à System.Data.Entity。 Core.Common.Internal.Materialization.Shaper1.SimpleEnumerator.MoveNext() à System.Collections.Generic.List
1..ctor(IEnumerable 1 source) à UncaGS.WcfServices.Repositories.Infrastructure.ReadOnlyGenericRepositoryBase 1 选择器,表达式1 collection)
à System.Linq.Enumerable.ToList[TSource](IEnumerable1.GetManyWithSelector[TOutput](Int32 startAt, Int32 take, Expression
1 where, Expression
1 orderBy, Expression`1[] includeProperties) --- Fin de la trace de la pile d'exception interne --- à System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor)à System .Reflection.RuntimeMethodInfo.UnsafeInvokeInternal(Object obj, Object[] parameters, Object[] arguments) → System.Delegate.DynamicInvokeImpl(Object[] args) → UncaGS.WcfServices.Services.GenericService.GenericService.GenericServiceWorker.ExecuteRequest(CallMethodContractBase callMethodContract,类型 repositoryType) à UncaGS.WcfServices.Services.GenericService.GenericService.GenericServiceWorker.Execute(CallMethodContractBase callMethodContract) à UncaGS.WcfServices.Services.GenericService.GenericService。ExecuteMethod(CallMethodContractBase callMethodContract) à SyncInvokeExecuteMethod(Object , Object[] , Object[] ) à System.ServiceModel.Dispatcher.SyncMethodInvoker.Invoke(Object instance, Object[] 输入, Object[]& 输出) à System.ServiceModel.Dispatcher。 DispatchOperationRuntime.InvokeBegin(MessageRpc& rpc) à System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage5(MessageRpc& rpc) à System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage11(MessageRpc& rpc) à System.ServiceModel.Dispatcher.MessageRpc.Process(Boolean isOperationContextSet)ServiceModel.Dispatcher.DispatchOperationRuntime.InvokeBegin(MessageRpc& rpc) à System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage5(MessageRpc& rpc) à System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage11(MessageRpc& rpc) à System.ServiceModel.Dispatcher.MessageRpc.Process(布尔 isOperationContextSet)ServiceModel.Dispatcher.DispatchOperationRuntime.InvokeBegin(MessageRpc& rpc) à System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage5(MessageRpc& rpc) à System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage11(MessageRpc& rpc) à System.ServiceModel.Dispatcher.MessageRpc.Process(布尔 isOperationContextSet)
解决方案
推荐阅读
- python - Python Gil 任务优化
- reactjs - 无法在基于反应的 spa 中使用 react-clear-cache 清除缓存
- javascript - 像这样进行 API 调用会导致性能问题吗?
- kotlin - 带有 readLine() 的用户输入 100 不被视为 Int 吗?科特林
- keycloak - 如何使用外部身份提供者设置 ACR 值
- stata - 多个 Stata 变量中所有值的平均值
- google-cloud-platform - 如何查看 GKE 集群的创建时间?
- azure-web-app-service - 来自手机浏览器的格式错误的语法
- amazon-web-services - 为什么 Terraform 计划在配置未更改的情况下重新创建块?
- angular - 如何在一个项目中使用多个 AWS Code Artifacts 包