System.Data.Entity.Infrastructure.CommitFailedException:C#多线程& SQL Server 2012 [英] System.Data.Entity.Infrastructure.CommitFailedException: C# Multithreading & SQL Server 2012

查看:767
本文介绍了System.Data.Entity.Infrastructure.CommitFailedException:C#多线程& SQL Server 2012的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们有一个C#多线程(100线程)程序,从DB读取记录,每个线程都会拾取一个记录(每个线程一个Entity Framework连接),并更新单个DB表。



对于前几分钟(5分钟),程序运行正常,无一例外,所有的所有线程都突然开始抛出以下错误消息..〜1分钟后,一切都会回到正常阶段..我认为SQL Server对于单个DB表(可能会尝试获取该表上的表锁)或连接到单个数据库并关闭所有连接的锁定太多。 / p>

我无法调试,有些人可以帮助我获取以下信息,


  1. SQL Server 2012在哪里存储其日志?


  2. 我们可以增加日志级别,以了解为什么在保存时会抛出异常DB实体


  3. 如何获取每个表的锁数,不同种类的锁(表锁,页锁,num行锁等) DB


  4. 任何其他指针来调试此问题。



$ b $我没有发现任何有用的东西sqlerror日志从这个cmd(SELECT SERVERPROPERTY('ErrorLogFileName'))



这是异常的堆栈跟踪


System.Data.Entity.Infrastructure.CommitFailedException:在提交数据库事务时报告错误,但无法确定数据库服务器上的事务是成功还是失败。查看内部异常,并 http://go.microsoft.com/fwlink/?LinkId=313468&hl=zh_CN 获取更多信息。



System.Data.SqlClient.SqlException:超时过期。在完成操作或服务器之前经过的超时时间没有响应。



System.ComponentModel.Win32Exception:等待操作超时



在System.Data.SqlClient.SqlInternalConnection。 OnError(SqlException异常,Boolean breakConnection,Action 1 wrapCloseInAction)

在System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj,Boolean callerHasConnectionLock,Boolean asyncClose)

在System.Data.SqlClient.TdsParserStateObject.ReadSniError(TdsParserStateObject stateObj,UInt32错误)

在System.Data.SqlClient.TdsParserStateObject.ReadSniSyncOverAsync()

在System.Data。 SqlClient.TdsParserStateObject.TryReadNetworkPacket()

在System.Data.SqlClient.TdsParserStateObject.TryPrepareBuffer()

在System.Data.SqlClient.TdsParserStateObject.TryReadByte(字节&值)

在System.Data.SqlClient.TdsParser.TryRun(RunBehavior runBehavior,SqlCommand cmdHandler,SqlDataReader dataStream,BulkCopySimpleResultSet bulkCopy处理器,TdsParserStateObject stateObj,Boolean& dataReady)

在System.Data.SqlClient.TdsParser.Run(RunBehavior runBehavior,SqlCommand cmdHandler,SqlDataReader dataStream,BulkCopySimpleResultSet bulkCopyHandler,TdsParserStateObject stateObj)

在System.Data.SqlClient.TdsParser .TdsExecuteTransactionManagerRequest(Byte [] buffer,TransactionManagerRequestType request,String transactionName,TransactionManagerIsolationLevel isoLevel,Int32 timeout,SqlInternalTransaction事务,TdsParserStateObject stateObj,Boolean isDelegateControlRequest)

在System.Data.SqlClient.SqlInternalConnectionTds.ExecuteTransactionYukon(TransactionRequest transactionRequest, String transactionName,IsolationLevel iso,SqlInternalTransaction internalTransaction,Boolean isDelegateControlRequest)

在System.Data.SqlClient.SqlInternalConnectionTds.ExecuteTransaction(TransactionRequest transactionRequest,String name,IsolationLevel iso,SqlInternalTransaction internalTransaction,Boolean isDelegateControlRequest )

在System.Data.SqlClient.SqlInternalTransaction.Commit()

在System.Data.SqlClient.SqlTransaction.Commit()

在System.Data .Entity.Infrastructure.Interception.DbTransactionDispatcher。< Commit> b__c(DbTransaction t,DbTransactionInterceptionContext c)

在System.Data.Entity.Infrastructure.Interception.InternalDispatcher
1.Dispatch [TTarget,TInterceptionContext](TTarget target,Action 2操作,TInterceptionContext interceptionContext,Action 3执行,Action`3执行)

---结束内部异常堆栈跟踪---



在System.Data.Entity.Infrastructure.Interception.InternalDispatcher 1.Dispatch [TTarget,TInterceptionContext](TTarget目标,Action 2操作,TInterceptionContext interceptionContext,Action 3执行,Action 3执行)

在System.Data.Entity .Infrastructure.Interception.DbTransactionDispatcher.Commit(DbTransaction transaction,DbInterception Context InterceptionContext)

在System.Data.Entity.Core.EntityClient.EntityTransaction.Commit()

在System.Data.Entity.Core.Objects.ObjectContext.ExecuteInTransaction [T] (Func 1 func,IDbExecutionStrategy executionStrategy,Boolean startLocalTransaction,Boolean releaseConnectionOnSuccess)

在System.Data.Entity.Core.Objects.ObjectContext.SaveChangesToStore(SaveOptions选项,IDbExecutionStrategy executionStrategy,Boolean startLocalTransaction )

在System.Data.Entity.Core.Objects.ObjectContext。  c__DisplayClass2a。< SaveChangesInternal> b__27()

在System.Data.Entity.SqlServer。 DefaultSqlExecutionStrategy.Execute [TResult](Func
1操作)

在System.Data.Entity.Core.Objects.ObjectContext.SaveChangesInternal(SaveOptions选项,Boolean executeInExistingTransaction)

在System.Data.Entity.Core.Objects.ObjectContext.SaveChanges(SaveOptions选项)

在System.Data.Entity.Internal.Intern alContext.SaveChanges()

在System.Data.Entity.Internal.LazyInternalContext.SaveChanges()

在System.Data.Entity.DbContext.SaveChanges()



解决方案

我曾经面对同样的sssue。如果线程应用程序对所有线程使用相同的上下文对象面对这些问题。
为每个线程创建单独的上下文对象。您可能会在RAM中添加更多的负载,但它可以清楚上下文中的enities的状态。

 列表与LT;任务> tasks = new List< Task>(); 
foreach(var item in list)
{
ObjectContext oContext = new ObjectContext(MyConnection);
任务t = Task.Factory.StartNew(()=>
{
this.Update(item,oContext);
});
tasks.Add(t);
}

Task.WaitAll(tasks.ToArray());


We have a C# multi threaded (100 threads) program which reads the records from the DB and each thread picks up one record (one Entity Framework connection per thread) and update the a single DB table.

For first few minutes (5 minutes) the program works fine without exception then all of a sudden all threads starts throwing the below error messages.. After ~1 min everything will come back to normal stage.. I think the SQL Server is getting too many locks for a single DB table (might be trying to acquire table lock on that table) or too many connections to a single DB and closing all the connections..

I am unable to debug this, can some one help me in getting the following information,

  1. Where does SQL Server 2012 store its logs?

  2. Can we increase the log level to see why it throws an exception while saving the DB entity

  3. How to get the number of locks per a table, different kind of locks (table lock, page lock, num row locks, etc) acquired by DB

  4. Any other pointers to debug this issue.

FYI, I didn't find anything useful in sqlerror log got from this cmd (SELECT SERVERPROPERTY('ErrorLogFileName'))

Here is the stack trace of the exception

System.Data.Entity.Infrastructure.CommitFailedException: An error was reported while committing a database transaction but it could not be determined whether the transaction succeeded or failed on the database server. See the inner exception and http://go.microsoft.com/fwlink/?LinkId=313468 for more information.

System.Data.SqlClient.SqlException: Timeout expired. The timeout period elapsed prior to completion of the operation or the server is not responding.

System.ComponentModel.Win32Exception: The wait operation timed out

at System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection, Action1 wrapCloseInAction)
at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj, Boolean callerHasConnectionLock, Boolean asyncClose)
at System.Data.SqlClient.TdsParserStateObject.ReadSniError(TdsParserStateObject stateObj, UInt32 error)
at System.Data.SqlClient.TdsParserStateObject.ReadSniSyncOverAsync()
at System.Data.SqlClient.TdsParserStateObject.TryReadNetworkPacket()
at System.Data.SqlClient.TdsParserStateObject.TryPrepareBuffer()
at System.Data.SqlClient.TdsParserStateObject.TryReadByte(Byte& value)
at System.Data.SqlClient.TdsParser.TryRun(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj, Boolean& dataReady)
at System.Data.SqlClient.TdsParser.Run(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj)
at System.Data.SqlClient.TdsParser.TdsExecuteTransactionManagerRequest(Byte[] buffer, TransactionManagerRequestType request, String transactionName, TransactionManagerIsolationLevel isoLevel, Int32 timeout, SqlInternalTransaction transaction, TdsParserStateObject stateObj, Boolean isDelegateControlRequest)
at System.Data.SqlClient.SqlInternalConnectionTds.ExecuteTransactionYukon(TransactionRequest transactionRequest, String transactionName, IsolationLevel iso, SqlInternalTransaction internalTransaction, Boolean isDelegateControlRequest)
at System.Data.SqlClient.SqlInternalConnectionTds.ExecuteTransaction(TransactionRequest transactionRequest, String name, IsolationLevel iso, SqlInternalTransaction internalTransaction, Boolean isDelegateControlRequest)
at System.Data.SqlClient.SqlInternalTransaction.Commit()
at System.Data.SqlClient.SqlTransaction.Commit()
at System.Data.Entity.Infrastructure.Interception.DbTransactionDispatcher.<Commit>b__c(DbTransaction t, DbTransactionInterceptionContext c)
at System.Data.Entity.Infrastructure.Interception.InternalDispatcher
1.Dispatch[TTarget,TInterceptionContext](TTarget target, Action2 operation, TInterceptionContext interceptionContext, Action3 executing, Action`3 executed)
--- End of inner exception stack trace ---

at System.Data.Entity.Infrastructure.Interception.InternalDispatcher1.Dispatch[TTarget,TInterceptionContext](TTarget target, Action2 operation, TInterceptionContext interceptionContext, Action3 executing, Action3 executed)
at System.Data.Entity.Infrastructure.Interception.DbTransactionDispatcher.Commit(DbTransaction transaction, DbInterceptionContext interceptionContext)
at System.Data.Entity.Core.EntityClient.EntityTransaction.Commit()
at System.Data.Entity.Core.Objects.ObjectContext.ExecuteInTransaction[T](Func1 func, IDbExecutionStrategy executionStrategy, Boolean startLocalTransaction, Boolean releaseConnectionOnSuccess)
at System.Data.Entity.Core.Objects.ObjectContext.SaveChangesToStore(SaveOptions options, IDbExecutionStrategy executionStrategy, Boolean startLocalTransaction)
at System.Data.Entity.Core.Objects.ObjectContext.<>c__DisplayClass2a.<SaveChangesInternal>b__27()
at System.Data.Entity.SqlServer.DefaultSqlExecutionStrategy.Execute[TResult](Func
1 operation)
at System.Data.Entity.Core.Objects.ObjectContext.SaveChangesInternal(SaveOptions options, Boolean executeInExistingTransaction)
at System.Data.Entity.Core.Objects.ObjectContext.SaveChanges(SaveOptions options)
at System.Data.Entity.Internal.InternalContext.SaveChanges()
at System.Data.Entity.Internal.LazyInternalContext.SaveChanges()
at System.Data.Entity.DbContext.SaveChanges()

解决方案

I used to face the same sssue.If the threaded app is using same context object for all the threads we face these kind of issues. Create separate context objects for each thread.You might be adding some more load on your RAM but it gives clarity about states of enities in Context.

List<Task> tasks = new List<Task>();
foreach (var item in list)
{
   ObjectContext oContext = new ObjectContext("MyConnection");
   Task t = Task.Factory.StartNew(() =>
   {
      this.Update(item,oContext);
   });
   tasks.Add(t);
}

Task.WaitAll(tasks.ToArray());

这篇关于System.Data.Entity.Infrastructure.CommitFailedException:C#多线程&amp; SQL Server 2012的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆