我tryng到一个数据库保存了多线程processo的日志,但我发现了以下错误:新的事务是不允许的,因为在会话中运行其他线程。
在每个胎面我有这样的功能:
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;
}
上下文是每个线程不同,但与数据库的连接始终是相同的。
有没有解决这个问题的方法吗?
谢谢安德烈
你应该为每个事务上下文,然后处理它,你可以是这样做的:
using(var ctx = new MyContext()) {
//do transaction here
}
闭合支架后的上下文被设置。
为了更好地理解参考这篇文章 ,你可以找到一个伟大的答案ken2k 。 希望你能解决您发出:)
更新:
你也应该尝试加入.ToList()
的每一个LINQ查询你有。 当我们通过遍历LINQ结果,直到迭代结束,你不能做任何修改。 检查您是否有类似的东西,或分享更多的代码,即在一段代码,你叫WriteTrace
。 希望这一次这实际上可以帮助你。
我使用实体框架在多线程环境下,任何线程,用户界面和后台(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;
文章来源: Entity Framework new transaction is not allowed because there are other threads running in the session, multi thread save