I have one piece of code that gets run on Application_Start for seeding demo data into my database, but I'm getting an exception saying:
The ObjectContext instance has been disposed and can no longer be used for operations that require a connection
While trying to enumerate one of my entities DB.ENTITY.SELECT(x => x.Id == value);
I've checked my code and I'm not disposing my context before my operation, Below is an outline of my current implementation:
protected void Application_Start()
{
SeedDemoData();
}
public static void SeedDemoData()
{
using(var context = new DBContext())
{
// my code is run here.
}
}
So I was wondering if Application_Start is timing out and forcing my db context to close its connection before it completes.
Note: I know the code because I'm using it on a different place and it is unit tested and over there it works without any issues.
Any ideas of what could be the issue here? or what I'm missing?
After a few hours investigating the issue I found that it is being caused by the data context having pending changes on a different thread. Our current implementation for database upgrades/migrations runs on a parallel thread to our App_Start method so I noticed that the entity I'm trying enumerate is being altered at the same time, even that they are being run on different data contexts EF is noticing that something is wrong while accessing the entity and returning an incorrect error message saying that the datacontext is disposed while the actual exception is that the entity state is modified but not saved.
The actual solution for my issue was to move all the seed data functions to the database upgrades/migrations scripts so that the entities are only modified on one place at the time.
Related
Background:
I have a web application in which I have SignalR as well.
I'm using AutoFac as DI container where my database is registered as
builder.RegisterType<MyDbContext>().AsSelf().InstancePerLifetimeScope();
i.e. MyDbContext is registered as PerRequestDependency.
The ChatHub is also registered with same dependency level. i.e.
builder.Register<IHubContext>((c) =>
{
return GlobalHost.ConnectionManager.GetHubContext<ChatHub>();
})
.InstancePerLifetimeScope();
Problem:
The problem I am facing is - The DbContext throws error saying there are multiple threads calling the DbContext.
Here is the exact error:
System.NotSupportedException: A second operation started on this context before a previous asynchronous operation completed. Use 'await' to ensure that any asynchronous operations have completed before calling another method on this context. Any instance members are not guaranteed to be thread safe. at System.Data.Entity.Internal.ThrowingMonitor.EnsureNotEntered()
Note: I have looked into entire code and I am 100% sure that I have awaited all async calls to the database.
Possible Solution:
If I change the AutoFac registration to per below then the error goes away but I feel, it will require more database connections.
builder.RegisterType<MyDbContext>().AsSelf();
i.e. remove InstancePerLifetimeScope
Expectation:
Better solution than increasing database connections.
Make sure you don't open the same entity twice.
Example:
var x = db.user.FirstOrDefault(a=>a.id == 1);
.
some code here
.
var y = db.user.FirstOrDefault(a=>a.id == 1);
y.userName = "";
I've been given an old WinForms app to update and improve. I am trying to add DI using SimpleInjector. I'm used to .Net MVC but this is my first time working with WinForms.
The application uses a lot of BackGround workers. My understanding is that this is specific to WinForms and each Background worker creates a new thread.
I think my problem is that when I want to save data to the DB using EF6 the SaveChanges method isn't able to save because of the multiple threads.
My SimpleInjector container is set up as follows
_container = new Container();
_container.Options.DefaultScopedLifestyle = new ThreadScopedLifestyle();
// Register DbContext
_container.Register<DbContext, MyDbContext>(Lifestyle.Scoped);
When I call SaveChanges on my dbContext I get a result of 0, which indicates that no records were saved to the database. In my debugger I get an error saying that the DbContext has been disposed. If this is happening before the save it explains why a 0 is returned from SaveChanges. Unfortunately the previous developer caught every exception so the application is trying to handle every error and this is making troubleshooting difficult and leading to unexpected behavior.
I am expecting a new DbContext to be created for each thread and that SaveChanges will save the changes made in each thread, so that what happens in one context won't affect other DbContexts in other threads.
When I am reading from the database I manually create a new DbContext in each method. Is it possible that when the using block has completed it is disposing the DbContext ?
using (var newDbContext = new MyDbContext())
{
return newDbContext.Set<TableA>().First(x => x.Id == id);
}
I'm hoping that if I have SimpleInjector configured correctly I won't need to do this either.
I'm a little lost at this stage and think I might not be understanding the documentation correctly, any advise would be greatly appreciated. Thanks in advance.
I am expecting a new DbContext to be created for each thread
This is not how TheadScopedLifestyle works. With the ThreadScopedLifestyle, there will be one instance of your registration within the context of an explicitly started Scope and this scope is thread-specific. This means that one thread can have many instances of that service, since a thread can live for a long time, while a Scope will typically only live for a short amount of time.
A typical use for ThreadScopedLifestyle is the following:
void MethodThatRunsInABackGroundThread()
{
using (ThreadScopedLifestyle.BeginScope(container))
{
var service = container.GetInstance<ISomeService>();
service.DoWork();
}
}
When you resolve Scoped instances (or some object graph that contains scoped instances) outside an active scope, Simple Injector will throw an exception.
We are using the SQLite.NET PCL in a Xamarin application.
When putting the database under pressure by doing inserts into multiple tables we are seeing BUSY exceptions being thrown.
Can anyone explain what the difference is between BUSY and LOCKED? And what causes the database to be BUSY?
Our code uses a single connection to the database created using the following code:
var connectionString = new SQLiteConnectionString(GetDefaultConnectionString(),
_databaseConfiguration.StoreTimeAsTicks);
var connectionWithLock = new SQLiteConnectionWithLock(new SQLitePlatformAndroid(), connectionString);
return new SQLiteAsyncConnection (() => { return connectionWithLock; });
So our problem turned out to be that although we had ensured within the class we'd written that it only created a single connection to the database we hadn't ensured that this class was a singleton, therefore we were still creating multiple connections to the database. Once we ensured it was a singleton then the busy errors stopped
What I've take from this is:
Locked means you have multiple threads trying to access the database, the code is inherently not thread safe.
Busy means you have a thread waiting on another thread to complete, your code is thread safe but you are seeing contention in using the database.
...current operation cannot proceed because the required resources are locked...
I am assuming that you are using async-style inserts and are on different threads and thus an insert is timing out waiting for the lock of a different insert to complete. You can use synchronous inserts to avoid this condition. I personally avoid this, when needed, by creating a FIFO queue and consuming that queue synchronously on a dedicated thread. You could also handle the condition by retrying your transaction X number of times before letting the Exception ripple up.
SQLiteBusyException is a special exception that is thrown whenever SQLite returns SQLITE_BUSY or SQLITE_IOERR_BLOCKED error code. These codes mean that the current operation cannot proceed because the required resources are locked.
When a timeout is set via SQLiteConnection.setBusyTimeout(long), SQLite will attempt to get the lock during the specified timeout before returning this error.
Ref: http://www.sqlite.org/lockingv3.html
Ref: http://sqlite.org/capi3ref.html#sqlite3_busy_timeout
I have applied the following solution which works in my case(mobile app).
Use sqlitepclraw.bundle_green nugget package with SqlitePCL.
Try to use the single connection throughout the app.
After creating the SQLiteConnection.
Apply busytime out using following call.
var connection = new SQLiteConnection(databasePath: path);
SQLite3.BusyTimeout(connection.Handle, 5000); // 5000 millisecond.
I have WebService that is hosted by ASP.NET web site. Inside the TransactionScope object is used to handle transactions:
using (TransactionScope scope = new TransactionScope())
{
...
scope.Complete();
}
The problem is that during debugging, when I am going through each line in step-by-step mode,
transaction timeout is occurred and any attempt to access DB crashed with '' error, and as a result: further debugging is prohibited.
How could I handle that without deleting mentioned lines of code?
P.S. I've tried to find, how to increase a time-out of created transaction, but didn't find something helpful.
Any thoughts are welcome.
Thanks.
You can specify an infinite timeout for the Transaction by passing in a zero length TimeSpan as part of the constructor:
using (TransactionScope scope = new TransactionScope(TransactionScopeOption.Required, new TimeSpan(0)))
The TransactionScopeOption of Required is what is used as default with your parameterless constructor.
See http://msdn.microsoft.com/en-us/library/ms172152(VS.90).aspx for more information.
I have a button in a .xhtml file which calls a javascript function which calls a java function remotely (in jboss seam environment). That java function has an entityManager.persist(object). Do you know why this line of code doesn't commit to the DB?
It says something that a transaction hasn't started. I supose in a remote context i don't have a transaction began because if i put an action on that button which calls the same java function instead of using javascript is above, it works fine; entityManager persists the object and i can see it in the DB.
Does anyone has any ideas how could i make to actually persist the object using javascript to call the java function? (i have to use javascript because i need the callback function )
To ensure a transaction You could extend org.jboss.seam.util.Work:
new Work()
{
#Override
protected Object work() throws Exception {
// do your stuff
return null;
}
}.workInTransaction()