1

Using autofac as my IoC framework.
I'd like to be able to set up my DbContext instance in my application's startup.

In my ASP.NET MVC 3 project, I register DbContext instance in Global.asax (PerLifetimeScope). But when I fire up my site on multiple browsers (or multiple tabs) at once, sometimes I get Object reference not set to an instance of an object. or New transaction is not allowed because there are other threads running in the session when I try to save changes back to database. Also I get ExecuteReader requires an open and available Connection. The connection's current state: Broken. sometimes when I want to read data from database.

the errors seem to pop up randomly and I suspect it has something to do with my context's lifetime scope. here's my DbContext's overriden SaveChange method.

public class MyContext : DbContext
{ 
    public override int SaveChanges()
    {
        var result = base.SaveChanges(); // Exception here
    }
}

Here's how I register my context:

builder.Register(c => new MyContext("SomeConnectionString"))
                 .InstancePerLifetimeScope(); 

If I just have one open tab of my site in the browser everything works ok.
Also, It's worth mentioning I have CRUD operations with db every 5-10 seconds in my website by calling a controller method using Ajax.

StackTrace for New transaction is not allowed because there are other threads running in the session:

at System.Data.EntityClient.EntityConnection.BeginDbTransaction(IsolationLevel isolationLevel)
at System.Data.EntityClient.EntityConnection.BeginTransaction()
at System.Data.Objects.ObjectContext.SaveChanges(SaveOptions options)
at System.Data.Entity.Internal.InternalContext.SaveChanges()
at System.Data.Entity.Internal.LazyInternalContext.SaveChanges()
at System.Data.Entity.DbContext.SaveChanges()
at MyProject.Data.MyContext.SaveChanges() in D:\Test.cs

StackTrace for Object reference not set to an instance of an object.:

at System.Data.Objects.ObjectStateManager.DetectConflicts(IList`1 entries)
at System.Data.Objects.ObjectStateManager.DetectChanges()
at System.Data.Entity.Internal.InternalContext.DetectChanges(Boolean force)
at System.Data.Entity.Internal.InternalContext.GetStateEntries(Func`2 predicate)
at System.Data.Entity.Internal.InternalContext.GetStateEntries()
at System.Data.Entity.Infrastructure.DbChangeTracker.Entries()
at System.Data.Entity.DbContext.GetValidationErrors()
at System.Data.Entity.Internal.InternalContext.SaveChanges()
at System.Data.Entity.Internal.LazyInternalContext.SaveChanges()
at System.Data.Entity.DbContext.SaveChanges()
at MyProject.Data.MyContext.SaveChanges() in D:\Test.cs   at 
Kamyar
  • 18,639
  • 9
  • 97
  • 171
  • does this help? http://stackoverflow.com/questions/6237280/new-transaction-is-not-allowed-because-there-are-other-threads-running-in-the-se – Boomer Jul 16 '12 at 13:54
  • My understanding is `InstancePerLifetimeScope` should handle Context creation/disposal for each `HttpRequest` separately. If not, then do you have any references to write a custom lifetime scope manager for my context? – Kamyar Jul 16 '12 at 13:56
  • I've noticed this issue as well – sky-dev Jul 30 '12 at 17:09

2 Answers2

1

Registration of MyContext looks ok. Is it possible that some other service that takes a MyContext is registered as a singleton and being shared across threads?

Jim Bolla
  • 8,265
  • 36
  • 54
  • Never thought of that. You were right about a singleton having access to context, but even after removing that, I still see weird context errors. I'll try to dig up more. – Kamyar Jul 17 '12 at 08:03
1

I had the same issue, sporadic errors related to the DbContext while using Autofac to resolve the DbContext.

{System.Data.EntityCommandExecutionException: An error occurred while executing the command definition. See the inner exception for details.
etc.

{System.NullReferenceException: Object reference not set to an instance of an object.
at System.Data.Objects.ObjectStateManager.DetectConflicts(IList`1 entries)
etc.

I found a class resembling the following in my code. The dependency resolution was occurring within a static method inside of the singleton. The object being resolved had a dependency on the DbContext. I haven't had any additional issues after I found a way to restructure this class so that it was no longer a singleton.

Perhaps you have a similar situation? Another thing to try might be to make your DbContext InstancePerHttpRequest. That could help identify whether this is the issue.

public class Singleton
{
    private static Singleton _instance = new Singleton();

    private Singleton()
    {

    }

    public static void DoSomething<TSource>(TSource source) where TSource : ISource
    {
        var items = DependencyResolver.Current.Resolve<IEnumerable<IDbContextConsumer<TSource>>>();
        foreach (var item in items)
        {
            item.Execute(source);
        }
    }
}
sky-dev
  • 6,190
  • 2
  • 33
  • 32