Base solution for your next web application
Open Closed

Optimistic Locking #4146


User avatar
0
PhilWynn created

Hi,

I am attempting to implement optimistic locking in order to handle concurrency issues.

I have added the following field to my entities:

[Timestamp]
public byte[] RowVersion { get; set; }

According to the EF documentation, this is all that is required, as long as the initial row version value is supplied with the update. However, I cannot seem to get this to work in ASPNet Zero.

Should I be implementing a custom repository to perform the updates? And if so, how do I prevent the update that is automatically called by the Unit Of Work manager?

Thank you

Markdown is supported
Copy & paste or drag & drop images (max 30 MB per image)

18 Answer(s)
  • User Avatar
    0
    aaron created
    Support Team

    Did you supply the initial row version? What's not working?

    You should not need to implement a custom repository for this.

    Markdown is supported
    Copy & paste or drag & drop images (max 30 MB per image)
  • User Avatar
    0
    PhilWynn created

    Hi,

    Basically, I am not getting a DbUpdateConcurrencyException when I perform a second update on stale data. I have checked that the row version updates in the database, but EF does not object to performing the second update with the old row version.

    Markdown is supported
    Copy & paste or drag & drop images (max 30 MB per image)
  • User Avatar
    0
    aaron created
    Support Team
    Markdown is supported
    Copy & paste or drag & drop images (max 30 MB per image)
  • User Avatar
    0
    PhilWynn created

    Many thanks, that is probably the issue I am having.

    The (best) solution to this problem is to set the Row Version in the Original Values collection prior to update. I will therefore need to override the update method. I assume the way to do this is via a custom repository?

    If so, how do I get the framework to call this rather than the default Update method? If I call it manually, how do I ensure that the default Update method doesn't get called by the Unit Of Work manager?

    Cheers

    Markdown is supported
    Copy & paste or drag & drop images (max 30 MB per image)
  • User Avatar
    0
    aaron created
    Support Team

    I will therefore need to override the update method. I assume the way to do this is via a custom repository?

    Actually, you might want to override ApplyAbpConceptsForModifiedEntity in YourDbContext instead (reason below).

    If so, how do I get the framework to call this rather than the default Update method? If I call it manually, how do I ensure that the default Update method doesn't get called by the Unit Of Work manager?

    The framework (and UnitOfWorkManager) doesn't call Update, but automatically saves changes (incl. ApplyAbpConcepts).

    Markdown is supported
    Copy & paste or drag & drop images (max 30 MB per image)
  • User Avatar
    0
    PhilWynn created

    Hi,

    I don't seem to have this method available. I am using v4 of Aspnet Zero, MVC, jQuery.

    Not quite sure how I would achieve my aim with this method anyway?

    Cheers

    Markdown is supported
    Copy & paste or drag & drop images (max 30 MB per image)
  • User Avatar
    0
    aaron created
    Support Team

    I don't seem to have this method available.

    Can you show what you did?

    Not quite sure how I would achieve my aim with this method anyway?

    Simple:

    protected override void ApplyAbpConceptsForModifiedEntity(DbEntityEntry entry, long? userId, EntityChangeReport changeReport)
    {
        if (entry.Entity is MyRowVersionEntity)
        {
            entry.OriginalValues["Timestamp"] = entry.CurrentValues["Timestamp"];
        }
    
        base.ApplyAbpConceptsForModifiedEntity(entry, userId, changeReport);
    }
    
    Markdown is supported
    Copy & paste or drag & drop images (max 30 MB per image)
  • User Avatar
    0
    PhilWynn created

    Thanks for the explanation.

    I have been unable to code anything, as the version of Abp I am using does not have the ApplyAbpConceptsForModifiedEntity method available for override. The Abp.EntityFramework dll is at version 2.01. I am using aspnet zero v4

    Markdown is supported
    Copy & paste or drag & drop images (max 30 MB per image)
  • User Avatar
    0
    aaron created
    Support Team

    You need Abp.EntityFramework v2.3.0, which should be compatible with ASP.NET Zero v4.0 to v4.4. ASP.NET Zero v4.5 to v4.6 should use Abp.EntityFramework v3.1.2.

    Markdown is supported
    Copy & paste or drag & drop images (max 30 MB per image)
  • User Avatar
    0
    PhilWynn created

    I'll update and give it a go.

    Many thanks.

    Markdown is supported
    Copy & paste or drag & drop images (max 30 MB per image)
  • User Avatar
    0
    PhilWynn created

    Many thanks, the system is now picking up concurrency issue.

    One final problem I am having. I cannot work out how to provide a sensible error message to the users in this instance. The Dynamic Web Api returns a generic message. Is there a way I can override this behaviour when encountering a concurrency exception?

    Cheers

    Markdown is supported
    Copy & paste or drag & drop images (max 30 MB per image)
  • User Avatar
    0
    aaron created
    Support Team

    You can override SaveChanges and SaveChangesAsync in YourDbContext:

    public override int SaveChanges()
    {
        try
        {
            return base.SaveChanges();
        }
        catch (DbUpdateConcurrencyException innerException)
        {
            throw new UserFriendlyException("Concurrency exception!", innerException.Message, innerException);
        }
    }
    
    Markdown is supported
    Copy & paste or drag & drop images (max 30 MB per image)
  • User Avatar
    0
    PhilWynn created

    Nice. Thank you.

    Markdown is supported
    Copy & paste or drag & drop images (max 30 MB per image)
  • User Avatar
    0
    PhilWynn created

    Hi,

    I am having an issue with the upgrade. I have the following service:

    Task<IEnumerable<SelectListItem>> GetPayrollGroupsForDropdown(long? userId);
    

    When I call this service via dynamic web with an 'undefined' parameter, I am getting the following validation error:

    "The value 'undefined' is not valid for Nullable'1"

    This has only started happening since the upgrade.

    Markdown is supported
    Copy & paste or drag & drop images (max 30 MB per image)
  • User Avatar
    0
    aaron created
    Support Team

    Please post a new topic. Remember to state which version you upgraded from and to.

    Markdown is supported
    Copy & paste or drag & drop images (max 30 MB per image)
  • User Avatar
    0
    tteoh created

    <cite>aaron: </cite> You need Abp.EntityFramework v2.3.0, which should be compatible with ASP.NET Zero v4.0 to v4.4. ASP.NET Zero v4.5 to v4.6 should use Abp.EntityFramework v3.1.2.

    Hi aaron,

    Which version should I upgrade to if I'm using MVC5AJ1? Because I'm not able to upgrade to the latest version, which is version 3.2.3 due to my .NETFramework is 4.6.1

    Thanks. /Tommy

    Markdown is supported
    Copy & paste or drag & drop images (max 30 MB per image)
  • User Avatar
    0
    aaron created
    Support Team

    Hi Tommy, can you try Abp.EntityFramework v2.3.0?

    Markdown is supported
    Copy & paste or drag & drop images (max 30 MB per image)
  • User Avatar
    0
    tteoh created

    <cite>aaron: </cite> Hi Tommy, can you try Abp.EntityFramework v2.3.0?

    Hi aaron,

    Able to update now.

    What should I do in order to get the exception? Follow the stackoverflow approach?

    Thanks. /Tommy

    Markdown is supported
    Copy & paste or drag & drop images (max 30 MB per image)