Entity Framework new transaction is not allowed because there are other threads running in the session, multi thread save

StackOverflow https://stackoverflow.com/questions/15363242

Question

I'm tryng to save on a DB the log of a multi thread processo but I'm getting the following error: new transaction is not allowed because there are other threads running in the session.

in each tread I have this function:

 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;

    }

the Context is different for each thread, but the connection with the DB is always the same.

is there a way to solve this problem?

thank you Andrea

Was it helpful?

Solution

You should create a context for each transaction and then dispose it, you can do that like this:

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

After the closed bracket the context is disposed.

For better understanding refer to this post where you can find a great answer by ken2k. Hope you can fix you issue :)

UPDATE:

You should also try adding .ToList() to every LINQ query you have. When you iterate over a LINQ result, you can't make any changes until the iteration has finished. Check if you have something like that or share more code i.e. the piece of code where you call WriteTrace. Hope that this time this actually helps you.

OTHER TIPS

I use entity framework in a multi-threaded environment, where any thread, ui and background (both STA and MTA), can concurrently update the same database. I resolved this problem by re-creating the entity connection from scratch at the start of usage on any new background thread. Examining the entity connection instance ConnectionString shows a reader guid which I assume is used to link common connection instances. By recreating the entity connection from scratch the guid values are different for each thread and no conflict appears to occur.

// 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;
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top