簡體   English   中英

當發生兩個並發更改時,為什么RowVersion屬性沒有引發樂觀並發異常?

[英]Why RowVersion property is not raising optimistic concurrency exception when two concurrent changes occur?

我有以下實體,

 public class PatientRegistry : BaseEntity {

        [Key, DatabaseGenerated(DatabaseGeneratedOption.None)]
        [Display(Name = "Patient File Number")]
        public long PatientFileId { get; set; }
        public virtual ICollection<PartnerRegistry> Partners { get; set; }
        public string UserId { get; set; }
        public string AliasName { get; set; }

        public DateTime? DateNow { get; set; }
        public virtual ApplicationUser User { get; set; }

    }

而BaseEntity是,

 public class BaseEntity : ISoftDelete {
        public bool IsDeleted { get; set; }

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

該實體具有RowVersion屬性,我使用流暢的API將其配置為RowVersion。 我使用存儲庫模式,這就是我在上下文中加載實體的方式,

 public async Task<PatientRegistry> GetPatient(long Id, bool isPartners = true, bool isUser = true) {
            if (isPartners && !isUser)
              return await context.PatientsRegistry
                .IgnoreQueryFilters()
                .Include(pt => pt.Partners)
                .Include(pt => pt.User)
                .Include(pt => pt.User.Gender)
                .Include(pt => pt.User.Nationality)
                .Include(pt => pt.User.Occupation)
                .Include(pt => pt.User.Ethnicity)
                .Include(pt => pt.User.MaritalStatus)
                .Include(pt => pt.User.Country)
                .Include(pt => pt.User.State)
                .Include(pt => pt.User.City)
                .Include(pt => pt.User.Database)
                .Include(pt => pt.User.UserAvatar)
                .SingleOrDefaultAsync(pt => pt.PatientFileId == Id);
        }

在我的控制器中,我更新如下,

[HttpPut("{FileId}")]
public async Task<IActionResult> UpdatePatient([FromRoute] PatientFileIdResource fileIdModel, [FromBody] SavePatientsRegistryResource model)
{
    ApiSuccessResponder<PatientRegistryResource> response = new ApiSuccessResponder<PatientRegistryResource>();
    if (!ModelState.IsValid)
        return BadRequest(ModelState);
    Task<PatientRegistry> getPatientTask = repository.GetPatient(fileIdModel.FileId.Value);
    Task<RequestHeaderResource> getHeaderRequestTask = headerRequestService.GetUserHeaderData();
    await Task.WhenAll(getPatientTask, getHeaderRequestTask);
    PatientRegistry patient = await getPatientTask.ConfigureAwait(false);
    RequestHeaderResource header = await getHeaderRequestTask.ConfigureAwait(false);
    if (patient == null)
    {
        ModelState.AddModelError(string.Empty, "The patient does not exist in the database");
        return BadRequest(ModelState);
    }

    patient.DateNow = DateTime.Now;
    patient.AliasName = model.AliasName;
    await unitOfWork.CompleteAsync(header);
    return StatusCode(200, response);
}

現在,如果我用兩個不同的用戶訪問其中一個記錄,並且其中一個alters AliasName並保存了另一個訪問記錄的用戶,那么在沒有發生並發異常的情況下,仍然可以保存新的更改。 為什么這里的並發更新沒有引發更新異常?

這是Fluent API配置,

 builder.Entity<PatientRegistry>()
        .Property(a => a.RowVersion).IsRowVersion()
        .IsConcurrencyToken()
        .ValueGeneratedOnAddOrUpdate();

我在這里有更新日志

更新

備查,

根據此處的文檔,我們可以通過在調用save之前操作一個值來測試並發沖突。

context.Database.ExecuteSqlCommand("UPDATE dbo.PatientsRegistry SET AliasName = 'Jane' WHERE PatientFileId = 2222");
await context.SaveChangesAsync();

這將引發一個例外。

如果從第二個用戶讀取是第一個用戶寫入之后 ,則第二個用戶的RowVersion將反映當時的值(即第一次更新之后)。 因此-沒有並發問題。

如果它們都讀取(並因此獲得相同的RowVersion ), 然后都嘗試寫入, 只會出現問題。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM