C# 不允许实体框架新事务,因为会话、多线程保存中有其他线程正在运行
我试图在DB上保存多线程进程的日志,但我得到以下错误:不允许新事务,因为会话中有其他线程在运行 在每个踏板中,我都有以下功能:C# 不允许实体框架新事务,因为会话、多线程保存中有其他线程正在运行,c#,multithreading,entity-framework-4,savechanges,C#,Multithreading,Entity Framework 4,Savechanges,我试图在DB上保存多线程进程的日志,但我得到以下错误:不允许新事务,因为会话中有其他线程在运行 在每个踏板中,我都有以下功能: internal bool WriteTrace(IResult result, string message, byte type) { SPC_SENDING_TRACE trace = new SPC_SENDING_TRACE( message,
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;
}
每个线程的上下文都不同,但与DB的连接总是相同的
有没有办法解决这个问题
多谢各位
Andrea您应该为每个事务创建一个上下文,然后对其进行处理,您可以这样做:
using(var ctx = new MyContext()) {
//do transaction here
}
在结束括号之后,上下文被释放
为了更好地理解,请参考您可以在何处找到一个很好的答案。希望您能解决您的问题:)
更新:
您还应该尝试将
.ToList()
添加到您的每个LINQ查询中。当您迭代LINQ结果时,在迭代完成之前无法进行任何更改。检查您是否有类似的内容或共享更多代码,即调用WriteTrace
的代码段。希望这次能对您有所帮助。我在多线程环境中使用entity framework,其中任何线程、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;
还是同一个错误,我有另一个主应用程序的上下文(不是多线程),但它在多线程运行时没有写入。它仍然会引起一些问题吗?@andrea主应用程序没有其他上下文,当您需要从数据库中请求、添加、删除或更新某些内容时,尝试创建一个上下文,使用
进行操作,就像我在回答每个事务时告诉您的那样,如果这不能解决问题,将锁添加到context.SaveChanges()
中。希望这能帮上忙,尽管我不太确定,所以,祝你好运!!!请无论如何回复;)如果我使用的是存储库模式。那么在这种情况下我该怎么办?@user1006544:我不明白你的问题,你的回购模式和这里发布的解决方案到底有什么问题?我出现这个错误是因为我使用了一个引用collection context.classname的循环。一旦我添加了“ToList()”错误就停止了。请不要复制并粘贴你对不同问题的大部分答案。