views:

74

answers:

3

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 from 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?

+3  A: 

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

Jan Jongboom
Downvote reason?
Jan Jongboom
Disposing DCs is not helpful
cottsak
+4  A: 

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)

Rob Kent
Thanks! I'm now creating a DC for each Unit of Work* and its working flawlessly.
ANaimi
That's how it's designed. The msdn page even uses the term "unit of work" - http://msdn.microsoft.com/en-us/library/system.data.linq.datacontext.aspx
cottsak
+1  A: 

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.

cottsak