Search code examples
c#linq-to-sqldatacontextsubmitchanges

Erratic LINQ to SQL Error: "operation cannot be performed during a call to SubmitChanges."


Okay, so I'm getting this error from the lines:

  System.Data.Linq.DataContext.CheckNotInSubmitChanges() +42
  System.Data.Linq.DataContext.SubmitChanges(ConflictMode failureMode) +54

What I'm doing is tracking an application's state and logging each request. The app renders output in Json, Xml and Html.

The thing is the error is erratic. It only happens every few requests. The error started happening when I started doing Ajax requests. I've been able to determine that the error occurs more frequently with rapid requests (i.e. if I click a link repeatedly).

I'm creating a separate instance of the DataContext each time I call the service that is throwing the error. I am having a really difficult time figuring out what the issue is here, and I would really appreciate any guidance and/or explanation as to what is happening. Thank you.

* EDIT : **

 [InvalidOperationException: The operation cannot be performed during a call to SubmitChanges.]
    System.Data.Linq.DataContext.CheckNotInSubmitChanges() +80
    System.Data.Linq.DataContext.SubmitChanges(ConflictMode failureMode) +73
    Magic.Model.Sessions.SqlXmlSessionStore.SubmitChanges() in SqlXmlSessionStore.cs:17
    Magic.Model.Sessions.SqlXmlSessionStore.UpdateSession(Session session) in SqlXmlSessionStore.cs:64
    Magic.Web.SessionService.OpenSession(MagicRequestContext requestContext) in SessionService.cs:36
    Magic.Web.SessionService.Magic.Model.Sessions.ISessionService.OpenSession(IRequestContext requestContext) in SessionService.cs:23

The methods mentioned are:

private bool SubmitChanges()
{
   _sqlContext.SubmitChanges(ConflictMode.FailOnFirstConflict);
   return _sqlContext.ChangeConflicts.Count == 0;   
}

public bool UpdateSession(Session session)
{
   var record = _sqlContext.SessionRecords.Single(x => x.SessionId == session.Key);
   _converter.PopulateRecordData(session, record);
   return SubmitChanges();
}

All the session service class does is call SqlXmlSessionStore.UpdateSession(session) if the session is in the db and active, or SqlXmlSessionStore.InsertSession(session) if the request is new and the session id is missing or unique.

I tried creating a new instance of the DataContext each time I did a SubmitChanges(), but that resulted in me not having a Connection object, even when I pull the same conn. string from settings. Could this be something having to do with my local machine?

Okay, so I did something that is working, but I am not sure if there will be a problem with this that I am not foreseeing.

I only allow the DataContext to submit once. I accomplished this by changing the SubmitChanges() code to:

    private bool _canSubmit = true;

    bool SubmitChanges(){
        if(_canSubmit)
        {
            _sqlContext.SubmitChanges(ConflictMode.FailOnFirstConflict);
            _canSubmit = false;
            return _sqlContext.ChangeConflicts.Count == 0;      
        }
        return false;
     }

This still seems like a very very hacky way for this to work, and I would like to get to the bottom of the issue, so please advise if anyone has any idea how to fix this.


Solution

  • There would have been no way to know this from my post, but I found the problem. I set up the dependency injection in an HttpModule, and there was a lock on the configuration function. I think it was there from old code I copied (and then forgot about) from somewhere when I was first learning how to use StructureMap. I removed the lock and it worked. (well, at least it began generating new, unrelated errors).

    Oh, and the reason it was affecting my DataContext was because the classes that wrapped instances of the Datacontext were inside the lock.