Question

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.

Was it helpful?

Solution 2

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.

OTHER TIPS

You can't change the change set inside of SubmitChanges and you can't call SubmitChanges in the overridden methods of the partial classes. I suspect you are doing this, but I don't completely follow your code fragments.

EDIT

I don't understand how the lifetime of the DataContext is being managed. In the first part of the question you say

I'm creating a separate instance of the DataContext each time I call the service

but in the second part you say

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

The next thing I don't understand is how your altered method that calls SubmitChanges only once works, since it discards any changes to the data made after it's first call it must either be not logging all of your data or any call after the first call to submit changes is not needed.

The instance methods of the Datacontext are not thread safe, you can't put it in a global variable at application start up (are you doing that?); you usually want a new Datacontext for each HTTP request, which you can do using an Inversion of Control framework or just in code, new up the dataconext at the beginning of the request and call submit changes at the end.

Another technique is to use several DataContexts, create the datacontext, make the changes, call submit chnages, discard the DataContext, it's very lightweight. You don't often need to call submit changes more than once, the only time I have done this is to control the execution order of the SQL statements.

It would be good if you could construct a minimal example and post the whole code.

I suggest you attach a debugger and catch the exception in the act. From there you should be able to trace where it is coming from.

Alternatively, override SubmitChanges and log the stacktrace on ever call to track down the original of the error.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top