13

我正在尝试将多线程进程的日志保存在数据库中,但出现以下错误:不允许新事务,因为会话中正在运行其他线程。

在每个胎面我都有这个功能:

 internal bool WriteTrace(IResult result, string message, byte type)
    {
        SPC_SENDING_TRACE trace = new SPC_SENDING_TRACE(
                        message,
                        Parent.currentLine.CD_LINE,
                        type,
                        Parent.currentUser.FULLNAME,
                        Parent.guid);
        Context.SPC_SENDING_TRACE.AddObject(trace);
        if (Context.SaveChanges(result) == false)
            return false;
        return true;

    }

每个线程的上下文不同,但与数据库的连接始终相同。

有没有办法解决这个问题?

谢谢安德里亚

4

2 回答 2

41

您应该为每个事务创建一个上下文,然后将其处理掉,您可以这样做:

using(var ctx = new MyContext()) {
    //do transaction here
}

在封闭的括号之后,上下文被处理。

为了更好地理解,请参阅这篇文章,您可以在ken2k中找到一个很好的答案。希望你能解决你的问题:)

更新:

您还应该尝试添加.ToList()到您拥有的每个 LINQ 查询中。迭代 LINQ 结果时,在迭代完成之前不能进行任何更改。检查您是否有类似的东西或共享更多代码,即您调用的代码段WriteTrace。希望这一次这对你有帮助。

于 2013-03-12T14:29:13.077 回答
0

我在多线程环境中使用实体框架,其中任何线程、ui 和后台(STA 和 MTA)都可以同时更新同一个数据库。我通过在任何新的后台线程上开始使用时从头开始重新创建实体连接来解决这个问题。检查实体连接实例 ConnectionString 显示了一个阅读器 guid,我假设它用于链接常见的连接实例。通过从头开始重新创建实体连接,每个线程的 guid 值都不同,并且似乎不会发生冲突。

// Build the connection string.

  var sqlBuilder = new SqlConnectionStringBuilder();
  sqlBuilder.DataSource = serverName;
  sqlBuilder.InitialCatalog = databaseName;
  sqlBuilder.MultipleActiveResultSets = true;
  ...
  var providerString = sqlBuilder.ToString();
  var sqlConnection = new SqlConnection(providerString);

// Build the emtity connection.

  Assembly metadataAssembly = Assembly.GetExecutingAssembly();
  Assembly[] metadataAssemblies = { metadataAssembly };
  var metadataBase = @"res://*/{0}.csdl|res://*/{0}.ssdl|res://*/{0}.msl";
  var dbModelMetadata = String.Format(metadataBase, objectContextTypeModelName);
  // eg: "res://*/Models.MyDatabaseModel.csdl|res://*/Models.MyDatabaseModel.ssdl|res://*/Models.MyDatabaseModel.msl"
  var modelMetadataPaths = modelMetadata.Split('|');
  var metadataWorkspace = new MetadataWorkspace(modelMetadataPaths, metadataAssemblies);
  var entityDbConnection = new EntityConnection(metadataWorkspace, sqlConnection);
  return entityDbConnection;
于 2016-02-17T00:07:07.707 回答