I have this web app that is running ASP .NET MVC 1.0 with LINQ 2 SQL
I'm noticing a very strange problem with LINQ 2 SQL throwing exceptions (mainly Specified cast invalid or Sequence contains more than one element) when under a certain amount of load.
The bigger problem is, I'm not talking about Real Heavy/Professional Stress Testing... Basically what I'm doing is I open FireFox and Chrome and hold down F5 for ten seconds in each (I call this poor man stress testing) - lo and behold; the web app is throwing these exceptions randomly for the next two or five minutes. If I restart the app from IIS7 (or restart WebDev if under Visual Studio) then immediately all is back to normal. Like nothing happened.
At first I was suspecting the way I handle the DataContext, maybe i'm supposed to dispose it at every Application_End from Global.asx, but that didn't change anything.
Right now I have a single public static DataContext object used by all requests. I'm not disposing it or re-creating it. Is that the right way to do it? Am I supposed to dispose it? When exactly should I dispose it?
There are several things that happen on every request - for example, in every page, the User object (for the current user) is loaded fr开发者_Go百科om the database and "LastSeen" attribute is updated to DateTime.Now. Other things (like Tag Cloud for example) are cached.
Any ideas why this is happening?
The DataContext class is not threadsafe - you need to create a new one for each operation. See this article by Rick Strahl (Linq to SQL DataContext Lifetime Management)
You should dispose the datacontext after every bunch of queries, and use it like
using(MyDataContext dc = new MyDataContext())
{
var x = dc.Table.Single(a=>a.Id=3);
//do some more related stuff, but make sure your connection won't be open too long
}
Don't have one static datacontext be used by every request. Would you use the same Connection object in normal ADO.Net for every request?!
See also http://blog.codeville.net/2007/11/29/linq-to-sql-the-multi-tier-story/
DataContext isn’t thread-safe, as far as I know
You lose isolation and cannot control when SubmitChanges() is called - concurrent requests will interfere with one another
Memory leaks are pretty likely
Create a DC for every operation like Rob suggests OR use a IoC container to have a DC shared per request.
DO NOT DISPOSE DC's - they are designed to be lightweight. Disposing is not only not necessary but it can cause bad practices and maybe other threading issues in the future which may be even harder to track down.
精彩评论