【问题标题】:Entity Framework exception: SqlConnection does not support parallel transactions实体框架异常:SqlConnection 不支持并行事务
【发布时间】:2019-07-18 15:02:53
【问题描述】:

我们有一个处理 XML 文件的应用程序。该应用程序使用 EF 6 将数据保存到 DB。应用程序使用 ThreadPool.QueueUserWorkItem 方法处理并发线程中的文件。该应用程序运行良好 1,5 年。 现在我们开始得到如下的 EF 异常:

大多数时候没有这样的错误,但是一天会出现几次。我们没有成功找出导致 EF 引发此错误的原因或条件。

有什么建议吗?

 An error occurred while starting a transaction on the provider connection. See the inner exception for details.
   at System.Data.Entity.Core.EntityClient.EntityConnection.BeginDbTransaction(IsolationLevel isolationLevel)
   at System.Data.Entity.Core.EntityClient.EntityConnection.BeginTransaction()
   at System.Data.Entity.Core.Objects.ObjectContext.ExecuteInTransaction[T](Func`1 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.Infrastructure.DbExecutionStrategy.Execute[TResult](Func`1 operation)
   at System.Data.Entity.Core.Objects.ObjectContext.SaveChangesInternal(SaveOptions options, Boolean executeInExistingTransaction)
   at System.Data.Entity.Internal.InternalContext.SaveChanges()
   at Albatross.Core.Utilities.BasicDataRepository`2.Update(T entity) in c:\DevTFS\AlbatrossEmployers\AlbatrossEmployers_DevTiyuvHeshb\Albatross.Core\Utilities\BasicDataRepository.cs:line 177
****** Inner Exception - START ******
SqlConnection does not support parallel transactions.
   at System.Data.SqlClient.SqlInternalConnection.BeginSqlTransaction(IsolationLevel iso, String transactionName, Boolean shouldReconnect)
   at System.Data.SqlClient.SqlConnection.BeginTransaction(IsolationLevel iso, String transactionName)
   at System.Data.SqlClient.SqlConnection.BeginDbTransaction(IsolationLevel isolationLevel)
   at System.Data.Entity.Infrastructure.Interception.InternalDispatcher`1.Dispatch[TTarget,TInterceptionContext,TResult](TTarget target, Func`3 operation, TInterceptionContext interceptionContext, Action`3 executing, Action`3 executed)
   at System.Data.Entity.Infrastructure.Interception.DbConnectionDispatcher.BeginTransaction(DbConnection connection, BeginTransactionInterceptionContext interceptionContext)
   at System.Data.Entity.Infrastructure.DbExecutionStrategy.Execute[TResult](Func`1 operation)
   at System.Data.Entity.Core.EntityClient.EntityConnection.BeginDbTransaction(IsolationLevel isolationLevel)
****** Inner Exception - END ******
~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Error - END ~~~~~~~~~~~~~~~~~~~~~~~~~~


The code is pretty simple:

     public virtual T Add(T entity)
        {
            try
            {
                using (U entityContext = new U())
                {
                    T addedEntity = Add(entity, entityContext);
                    entityContext.SaveChanges();
                    return addedEntity;
                }
            }
            catch (DbEntityValidationException e)
            {
                var msg = FormatDbValidationErrors(e);
                throw new Exception(msg);
            }
            catch (Exception ex)
            {
                AmanLog.Logger.Error(ex);
                throw;
            }
        }


 public virtual T Update(T entity)
        {
            try
            {
                using (U entityContext = new U())
                {
                    T existingEntity = Update(entity, entityContext);
                    entityContext.SaveChanges();
                    return existingEntity;
                }
            }
            catch (DbEntityValidationException e)
            {
                var msg = FormatDbValidationErrors(e);
                throw new Exception(msg);
            }
            catch (Exception ex)
            {
                AmanLog.Logger.Error(ex);
                throw;
            }
        }

【问题讨论】:

标签: c# entity-framework entity-framework-6


【解决方案1】:

应用程序使用 ThreadPool.QueueUserWorkItem 方法处理并发线程中的文件。

您不能从两个线程同时使用相同的连接,否则:会发生这种情况。要么:

  • 通过单个连接/数据库上下文进行同步,这样就不能一次使用两次(lock 是实现此目的的简单方法)
  • 使用每个工作项的连接/数据库上下文,以便不共享任何内容

【讨论】:

  • 我们不会在不同的线程中使用相同的 DBContext,否则,应用程序根本无法工作......每个线程都会初始化 DbContext 的新实例。因此,我们无法理解为什么每天会抛出几次 (10-20) 次此错误(该应用每天处理多达 2 万个文件)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-10-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-09-06
相关资源
最近更新 更多