Concurrency Error

May 23, 2013 at 8:41 AM
Hi Guys,
           I have been testing my site and when I do repeated quick updates of an object I am getting the concurrency error below.
I just tried changing a string property of my object a few times fairly quickly and I can get this error easily. I think it may be due to the slow network on this gov site I am on.

Should I check for anything or just say its due to a slow network?

Here is the error.

Concurrency Error

The object you were viewing was out of date. Your action/edit has not been applied, you may return to the object which has now been reloaded and try your action/edit again. Original Error: Store update, insert, or delete statement affected an unexpected number of rows (0). Entities may have been modified or deleted since entities were loaded. Refresh ObjectStateManager entries.

Regards,
            Alistair
Coordinator
May 23, 2013 at 9:16 AM
First, I assume you have read the section on How to handle Concurrency Checking in the manual and are using this.

We are not aware of any problem with the Concurrency Checking in NOF - which is well tested.

If you are updating very frequently and operating on a slow network - then you run the risk of overlapping asynchronous requests. In which case the fact that you are getting this message is probably just a sign that concurrency checking is in fact working correctly.
May 23, 2013 at 10:27 AM
Yes all of my objects have the [ConcurrencyCheck] as per your doco

[Disabled]
    [ConcurrencyCheck] // This property will be used for concurrency checking i.e. to check if another user has updated
    // the object before this copy of the object can be saved
    public override DateTime ModifiedDate { get; set; }
I will try and test what the network latency is.

Best Regards,
              Alistair
May 27, 2013 at 6:14 AM
Here is another example of this error
I have action methods on an object that just change the an enum value
[MemberOrder(5)]
        public void PractitionerAcceptedOffer()
        {
            OfferState = OfferState.Accepted;
                 }

        [MemberOrder(6)]
        public void PractitionerRejectedOffer()
        {
            OfferState = OfferState.Rejected;            
         }
I can perform one of these actions once.
Then if I try and perform the other action I get the error as above.

Do I have to reload the object somehow after each update?

I tried calling the
Container.ObjectChanged(this)
or the
Container.Refresh(this)

after the update but this did not work.

I will have to try this on another machine.

Regards,
           Alistair
Editor
May 27, 2013 at 6:17 AM
There's no need to reload the object; NO MVC is a stateless architecture.

To help, I need more info, please.

How have you configured concurrency? Are you using [ConcurrencyCheck] somewhere? Or are you using Fluent API? What's the datatype of the property - timestamp or datetime?




May 27, 2013 at 6:24 AM
And my base business object has the following code
public virtual void Persisting() {
            rowguid = Guid.NewGuid();
            ModifiedDate = DateTime.Now;
        }

        public virtual void Updating() {
            ModifiedDate = DateTime.Now;
        }
Editor
May 27, 2013 at 7:47 AM
OK, your code does look correct to me (I noticed earlier in the thread you said you are using [ConcurrencyCheck] with a DateTime).

The object is reloaded on each request, so invoking two actions one after the other should not trigger the exception.

It'd be useful to see what update SQL is being submitted immediately prior to the exception being thrown. Can you attach SQL profiler to obtain a trace?


May 27, 2013 at 9:18 AM
Thanks mate, yes I am using the ConcurrencyCheck attribute on my objects.
The doco says

Warning
If you have any inheritance within your domain model, then the ConcurrencyCheck attribute should be applied to a property on the top-most class of each hierarchy, and should not be duplicated within any sub-classes. (Sub-classes may have their own LastUpdated or similar properties for other purposes, but these do not play a role in concurrency checking.)

But in the sample code each domain object has a overridden ModifiedDate, it looks the doco should say why you have to override concurrency properties.

I ran the trace but the TextData line is being truncated. We are using SQL Server 2008 R2. Do you know how to see the whole trace line?
I can't see what values are being sent for the ModifiedDate fields.

Regards,
             Alistair
May 29, 2013 at 4:48 AM
Edited May 29, 2013 at 4:51 AM
Hi Guys,
            I have got the concurrency check working using a Timestamp as shown instead of the ModifiedDate.
So in my base domain class I have.
public virtual void Persisting() {
            rowguid = Guid.NewGuid();
            ModifiedDate = DateTime.Now;
            Timestamp = Stopwatch.GetTimestamp();
        }

        public virtual void Updating() {
            ModifiedDate = DateTime.Now;
            Timestamp = Stopwatch.GetTimestamp();
        }

        #endregion
        
        public abstract long Timestamp { get; set; } // abstract as the Timestamp must be implemented by derived classes.
Maybe this is an issue with EF 5 which I am using.

Regards,
            Alistair
Coordinator
May 29, 2013 at 8:23 AM
While I am glad that you got something working, I must stress that Naked Objects concurrency does work with DateTime - and that is what we use in our testing. I think it more likely that when you added your Timestamp, you were making a fresh start and you did (or didn't) do something else differently that was causing the problem before.
Maybe this is an issue with EF 5 which I am using.
EF5 is what we test against.