none
DbUpdateConcurrencyException is not raised RRS feed

  • Question

  • The DbUpdateConcurrencyException is not raised in my case. I'm using Database first approach in EF 5.0 I have Carrier object with 0..1 relationship with Address & Contact objects.

    I have created the a RowVersion field in the Carrier table .

    My code is as follows:

    public Carrier UpdateCarrier(Carrier carrier)
        {
            try
            {
                var entry = ariesConfigContext.Entry<Carrier>(carrier);
                if(entry.State == System.Data.EntityState.Detached)
                {
                    var attachedEntity = ariesConfigContext.Carriers.Include(con => con.Contact).Include(a => a.Address).Single(c => c.CarrierID == carrier.CarrierID);
                    if(attachedEntity != null)
                    {
                        var attachedEntry = ariesConfigContext.Entry(attachedEntity);
                        attachedEntry.CurrentValues.SetValues(carrier);
                        attachedEntity.Contact = carrier.Contact;
                        attachedEntity.Address = carrier.Address;
                    }
                    else
                    {
                        entry.State = System.Data.EntityState.Modified;
                    }
                }              
                ariesConfigContext.SaveChanges();
            }
            catch(DbUpdateConcurrencyException ex)
            {
                //do something
            }
            return carrier;
        }

    My Model is as follows:

    namespace Aries.Domain.Models.AriesConfigDB { using System; using System.Collections.Generic; public partial class Carrier { public Carrier() { this.UserProfiles = new HashSet<UserProfile>(); } public int CarrierID { get; set; } public string Name { get; set; } public string Abbreviation { get; set; } ... ... public byte[] RowVersion { get; set; } public virtual Address Address { get; set; } public virtual Contact Contact { get; set; } public virtual ICollection<UserProfile> UserProfiles { get; set; } } }

    [MetadataType(typeof(CarrierMetadata))] public partial class Carrier { } public class CarrierMetadata { public int CarrierID { get; set; } [Required] [MaxLength(255, ErrorMessage = "Carrier Name must be 255 characters or less")] [Display(Name = "Carrier Name")] public string Name { get; set; } .... .... [Required] [ConcurrencyCheck] [Timestamp] public byte[] RowVersion { get; set; } }


    My View is:

    @model Aries.Domain.Models.AriesConfigDB.Carrier
    
    <div>
    <div class="message-error">
        @if (TempData["ErrorMessage"] != null)
        {
            <p>@TempData["ErrorMessage"]</p>
        }
    </div>
    
    @Html.HiddenFor(model => model.CarrierID)
        @Html.HiddenFor(model => model.RowVersion)
    
    <div class="editor-label">
        @Html.LabelFor(model => model.Name)
    </div>
    <div class="editor-field">
        @Html.EditorFor(model => model.Name)
        @Html.ValidationMessageFor(model => model.Name)
    </div>
    
    <div class="editor-label">
        @Html.LabelFor(model => model.Abbreviation)
    </div>
    ....
    ....
    I'm unable to get the Exception to be raised. Any help is appreciated.
    • Edited by Hetal Shah Wednesday, May 15, 2013 10:44 PM
    Wednesday, May 15, 2013 10:43 PM

Answers

  • On 5/17/2013 5:11 PM, Hetal Shah wrote:


    @Patrice Scribe:

    * Even if I remove ConcurrencyCheck it doesn't work. FYI, I've set Concurrency = Fixed on the EDMX for this field. I added it to the metadata just as a double check. But I've tried it without that attribute too.
    * Timestamp  - SQL Server is the database. Yes, column is automatically updated.
    * I've not enabled trace yet, but plan to do so.
    * The VS settings are correct and do not ignore exceptions. I execute the application in the Debug mode to see if this exception is caught or not. But no exceptions are thrown, the latest request is saved to the database successfully. It's always last edit wins.

    The simplest and the most effective way to do a concurrency check on an update is to do a LastUpdateDate check. You put a LastUpdateDate column (System.DateTime) on the table. The table get's updated, you set the LastUpdateDate to Date.Now on the table record.

    Before you try to update the record, you read the current record from the database. You compare the LastUpdateDate on the record you are trying to save against the one you just pulled from the database, a check. If the two datetimes don't match, then you know someone updated the record and saved it before the one you are currently trying to save could be saved.

    If the two datetimes are equal, then you can proceed with the save, because you know no one saved the record first prior to you trying to do the save.
     Sometimes, simpler is better.

    Saturday, May 18, 2013 9:19 PM

All replies

  • Please check this link that has a section for Concurrency Check:

    http://msdn.microsoft.com/en-us/data/gg193958.aspx

    Thursday, May 16, 2013 9:16 PM
  • Thanks, but I believe I've implemented everything mentioned there. If you notice something missing, pls do let me know.

    Thursday, May 16, 2013 11:29 PM
  • Hi,

    Are you sure you need both ConcurrencyCheck and TimeStamp ?

    What is the column type database side ? Have you checked this column is updated automatically ?

    I would likely start by using a trace to see which SQL statements are sent database side.  It would allow to make 100% wether or not concurrency checks are done.

    If really done, it could be perhaps a VS setting (Debug/Exceptions allows to ignore exceptions). BTW how do you know your code doesn't go there ? The code you shown us have nothing in the catch clause.


    Please always mark whatever response solved your issue so that the thread is properly marked as "Answered".



    Friday, May 17, 2013 4:15 PM
  • @Patrice Scribe:
    • Even if I remove ConcurrencyCheck it doesn't work. FYI, I've set Concurrency = Fixed on the EDMX for this field. I added it to the metadata just as a double check. But I've tried it without that attribute too.
    • Timestamp  - SQL Server is the database. Yes, column is automatically updated.
    • I've not enabled trace yet, but plan to do so.
    • The VS settings are correct and do not ignore exceptions. I execute the application in the Debug mode to see if this exception is caught or not. But no exceptions are thrown, the latest request is saved to the database successfully. It's always last edit wins.



    • Edited by Hetal Shah Friday, May 17, 2013 9:11 PM
    Friday, May 17, 2013 9:11 PM
  • On 5/17/2013 5:11 PM, Hetal Shah wrote:


    @Patrice Scribe:

    * Even if I remove ConcurrencyCheck it doesn't work. FYI, I've set Concurrency = Fixed on the EDMX for this field. I added it to the metadata just as a double check. But I've tried it without that attribute too.
    * Timestamp  - SQL Server is the database. Yes, column is automatically updated.
    * I've not enabled trace yet, but plan to do so.
    * The VS settings are correct and do not ignore exceptions. I execute the application in the Debug mode to see if this exception is caught or not. But no exceptions are thrown, the latest request is saved to the database successfully. It's always last edit wins.

    The simplest and the most effective way to do a concurrency check on an update is to do a LastUpdateDate check. You put a LastUpdateDate column (System.DateTime) on the table. The table get's updated, you set the LastUpdateDate to Date.Now on the table record.

    Before you try to update the record, you read the current record from the database. You compare the LastUpdateDate on the record you are trying to save against the one you just pulled from the database, a check. If the two datetimes don't match, then you know someone updated the record and saved it before the one you are currently trying to save could be saved.

    If the two datetimes are equal, then you can proceed with the save, because you know no one saved the record first prior to you trying to do the save.
     Sometimes, simpler is better.

    Saturday, May 18, 2013 9:19 PM