How to handle OptimisticConcurrencyException

Oct 22, 2012 at 10:33 AM
Edited Oct 22, 2012 at 10:35 AM

I am trying to handle OptimisticConcurrencyException using following codes

var context = ((ObjectQuery)Container.Instances<Reservation>()).Context;
    try
            {
                context.SaveChanges();
                return true;
            }
            catch (OptimisticConcurrencyException ex)
            {
                foreach (var item in context.ObjectStateManager.GetObjectStateEntries(EntityState.Modified))
                {
                    context.Refresh(RefreshMode.StoreWins, item.Entity);
                }
                foreach (var item in context.ObjectStateManager.GetObjectStateEntries(EntityState.Added))
                {
                    context.Detach(item.Entity);
                }
                return false;
            }

But getting error "System.NullReferenceException: Object reference not set to an instance of an object". I think updating DBContext in this way, NakedObject framework loosing objects/control.

Is there any better way to handle OptimisticConcurrencyException?

OptimisticConcurrencyException
Coordinator
Oct 22, 2012 at 11:29 AM

The OptimisticConcurrencyException is handled by the Naked Objects Framework for you. The transaction will fail and the user will be told to try again. There's no need to do anything with the context as that context will be discarded at the end of the transaction.

If you want to change this behaviour then you can take a look at the code in the NakedObjects.Mvc project or more fundamentally in the Nakedobjects.Entity.Persistor project.

Just grabbing the context and doing SaveChanges is going to interfere in unpredictable ways with the NakedObjects Framework Persistor code and I would strongly suggest you don't do it.

 

 

 

 

Oct 22, 2012 at 11:43 AM
Edited Oct 22, 2012 at 11:46 AM

What if I return custom view from my custom made controller (inheriting CustomController)? Still The transaction will fail and the user will be told to try again? Do I need to implement custom error handler?

Coordinator
Oct 22, 2012 at 11:59 AM

The transaction will fail in the Entity Persistor and you will see a 'ConcurrencyException' that wraps the OptimisticConcurrencyException. 

You can then add an 'OnException' Handler to your custom controller - in the same way as the  GenericControllerImpl eg

 

 protected override void OnException(ExceptionContext filterContext) {
            if (filterContext.Exception is ConcurrencyException) {
                filterContext.Result = View("ConcurrencyError", filterContext.Exception);
                filterContext.ExceptionHandled = true;
            }
               
            base.OnException(filterContext);
        }

Oct 22, 2012 at 12:50 PM
Edited Oct 22, 2012 at 12:54 PM

I have added an 'OnException' Handler in my custom controller. I am also using try-catch in my action method and logging the error.

4 users are testing the system simultaneously to produce concurrency exception. The results are

user1 gets "ConcurrencyException" but in log "System.NullReferenceException: Object reference not set to an instance of an object"

user2 gets "ConcurrencyException" but in log "System.NullReferenceException: Object reference not set to an instance of an object"

user3 does not get "ConcurrencyException", getting "System.NullReferenceException: Object reference not set to an instance of an object" error and in log "System.NullReferenceException: Object reference not set to an instance of an object"

user4 gets "ConcurrencyException" but no error in log.

I am getting unpredictable behavior of NakedObjects.

BUT when 2 users are testing the system simultaneously to produce concurrency exception , it is working fine.

Any suggestion?

 

Coordinator
Oct 22, 2012 at 1:31 PM

The System.NullReferenceExceptions - are they coming from inside the framework (if so please supply a stack trace) or are they in your custom code ?

Coordinator
Oct 22, 2012 at 8:49 PM

If you think you are experiencing 'unpredictable behaviours' with Naked Objects, I would ask you to see if you can reproduce it with a completely generic Naked Objects run project (no custom views or controllers).  I always recommend to developers that as soon as they start to write any kind of custom view, JavaScript, or, especially, custom controllers  -  that you maintain a completely generic Naked Objects Run MVC project along side it.  YOu can then simply switch between the run projects to check out any problems you are seeing.

While it is always possible that there is a problem with Naked Objects  -  in which case we will fix it  -  if you are writing custom controllers, there is quite a high likelihood that that is the cause of the issue  -  especially given your earlier posting where you appeared to be doing things directly with the context.

If you can reproduce the problem with the generic views and controllers, please include full stack traces for the errors you see.

Oct 23, 2012 at 6:09 AM

I am doing some testing. As soon as I'll confirm about the error, I'll post it.

Oct 23, 2012 at 12:39 PM

My observation is, whenever concurrency happened, my domain object is set to null by framework for all cases even the winner one too. But in winning situation domain object should as it is.

I am doing some operation in view using that domain object and getting "System.NullReferenceException" when concurrency happened.

So, what I did, in view I have reload the domain object if I get null in domain object and thus resolved the "System.NullReferenceException" issue.