آموزش مدیریت همزمانی – Concurrency در EF Core

آموزش مدیریت همزمانی – Concurrency در EF Core

در برنامه‌هایی که چند کاربر به‌صورت همزمان داده‌ها را مشاهده یا ویرایش می‌کنند، نیاز به یک سیستم مطمئن برای جلوگیری از بروز تعارض – Conflict بین عملیات کاربران وجود دارد. این مسئله در EF Core از طریق مدیریت همزمانی یا Concurrency Handling کنترل می‌شود. در این آموزش به‌صورت کامل با مفاهیم تئوری و عملی مدیریت همزمانی آشنا خواهید شد. و روش‌های مختلف جلوگیری و حل Conflictها در EF Core را بررسی می‌کنیم. با ما همراه باشید با آموزش مدیریت همزمانی – Concurrency در EF Core و Asp.Net Core.

انواع همزمانی در EF Core

همزمانی – Optimistic Concurrency : در این مدل، فرض بر این است که Conflict به‌ندرت رخ می‌دهد. کاربران می‌توانند به‌صورت همزمان داده‌ها را بخوانند و هنگام ذخیره، بررسی می‌شود که آیا داده‌ها تغییر کرده‌اند یا خیر.

همزمانی Pessimistic Concurrency : در این مدل، رکوردها قبل از ویرایش قفل می‌شوند. در EF Core به‌صورت مستقیم پشتیبانی نمی‌شود اما با استفاده از دستورات SQL و Transactionها قابل پیاده‌سازی است.

Concurrency Conflict چیست؟

فرض کنید دو کاربر به‌صورت همزمان اطلاعات یک مشتری را ویرایش می‌کنند. اگر هر دو تغییرات را ذخیره کنند، بدون مدیریت همزمانی یکی از تغییرات از بین خواهد رفت. این وضعیت را Concurrency Conflict می‌نامند.

استفاده از [ConcurrencyCheck] و [Timestamp]

برای کنترل همزمانی می‌توان از Data Annotationهایی مانند [ConcurrencyCheck] یا [Timestamp] استفاده کرد. معمولاً از نوع byte[] برای Timestamp استفاده می‌شود که به‌صورت rowversion در SQL Server ذخیره می‌گردد.

public class Customer
{
   public int Id { get; set; }
   public string Name { get; set; }
   [Timestamp]
   public byte[] RowVersion { get; set; }
}

پیکربندی با Fluent API

در Fluent API نیز می‌توان فیلد همزمانی را به‌صورت زیر تعریف کرد:

modelBuilder.Entity<Customer>()
.Property(c => c.RowVersion)
.IsRowVersion();

مدیریت DbUpdateConcurrencyException

در صورت بروز Conflict، EF Core یک استثناء به نام DbUpdateConcurrencyException پرتاب می‌کند. برای مدیریت آن:

try
{
    await context.SaveChangesAsync();
}
catch (DbUpdateConcurrencyException ex)
{
    foreach (var entry in ex.Entries)
    {
        var databaseValues = await entry.GetDatabaseValuesAsync();
        // مقایسه مقدار فعلی با مقدار دیتابیس و انتخاب بهترین راه‌حل
    }
}

روش‌های متداول برای حل Conflict

  • روش Client Wins: داده‌های سمت کاربر حفظ شود.
  • روش Store Wins: داده‌های دیتابیس حفظ شود.
  • روش Merge: ترکیب مقادیر و ذخیره‌سازی مجدد.
public async Task<IActionResult> Edit(int id, [Bind("Id,Name,BankName,RowVersion")] Banker banker)
{
    if (id != banker.Id)
        return NotFound();

    if (!ModelState.IsValid)
        return View(banker);

    //اطلاعات ردیابی بانکر را بیار تا فیلد مورد نظر خود را مقدار دهی کنم
    _context.Entry(banker).Property(a => a.RowVersion).OriginalValue = banker.RowVersion;

    try
    {
        _context.Update(banker);
        await _context.SaveChangesAsync();
        return RedirectToAction(nameof(Index));
    }
    catch (DbUpdateConcurrencyException ex)
    {
        foreach (var entry in ex.Entries)
        {
            var DbValue = await entry.GetDatabaseValuesAsync();
            if (DbValue == null)
            {
                TempData["ErrorMessage"] = "recorde morede nazar hazfe shode ast";
                return RedirectToAction(nameof(Index));
            }

            var DatabaseValues = (Banker)DbValue.ToObject();
            var CurrentValues = (Banker)entry.CurrentValues.ToObject();
            var OriginalValues = (Banker)entry.OriginalValues.ToObject();

            //Store Wins
            //entry.OriginalValues.SetValues(DatabaseValues);
            //entry.CurrentValues.SetValues(DatabaseValues);
            //TempData["ErrorMessage"] = "ghable shoma in record viraiesh shode ast etelate shoma zakhire nashod";

            //Client Wins
            //entry.OriginalValues.SetValues(DatabaseValues);
            //TempData["ErrorMessage"] = "در زمان ویرایش شما رگورد ویرایش شده بود ولی اطلاعات شما چایگزین شد";
        }

        await _context.SaveChangesAsync();
        return RedirectToAction(nameof(Index));
    }
}

آشتایی با متد های مرسوم Conflict

مدیریت همزمانی در EF Core یکی از مباحث مهم برای تضمین سلامت داده‌ها در برنامه‌های چندکاربره است. با استفاده از RowVersion، Attributeهای EF Core و مدیریت درست Conflictها می‌توان سیستم قابل اعتمادی برای ویرایش داده‌ها ایجاد کرد.

مفهومتوضیح
CurrentValuesداده‌هایی که از سمت کاربر ارسال شده و EF Core قصد دارد آن‌ها را روی دیتابیس ذخیره کند. این مقادیر همان چیزی هستند که از فرم یا API آمده و آماده‌ی ذخیره‌سازی‌اند.
OriginalValuesنسخه‌ای از رکورد که EF Core هنگام بارگذاری اولیه موجودیت از دیتابیس خوانده و برای تشخیص تغییرات نگه داشته است. اختلاف این مقادیر با DatabaseValues منجر به Conflict می‌شود.
DatabaseValuesمقادیر واقعی و فعلی رکورد در دیتابیس، یعنی همان چیزی که در لحظه‌ی رخ دادن Conflict از دیتابیس خوانده می‌شود. این نسخه ممکن است توسط کاربر دیگری ذخیره شده باشد.
RowVersionفیلدی از نوع byte[] که در دیتابیس (SQL Server) به‌صورت خودکار و یکتا با هر تغییر مقدار جدیدی می‌گیرد. EF Core از این فیلد برای تشخیص دقیق تغییرات همزمان استفاده می‌کند.
CurrentValues.SetValuesمتدی برای جایگزین‌کردن مقادیر فرم با مقدار دیتابیس. در استراتژی‌هایی مانند Store Wins برای لغو تغییرات کاربر و پذیرش مقدار دیتابیس استفاده می‌شود.
OriginalValues.SetValuesمتدی برای به‌روزرسانی وضعیت اصلی Entity با مقدار جدید از دیتابیس. در همه استراتژی‌ها پس از حل Conflict برای هماهنگ‌کردن EF با وضعیت جدید لازم است.
DbUpdateConcurrencyExceptionاستثنایی که هنگام اجرای SaveChanges() و عدم تطابق RowVersion رخ می‌دهد. نشان می‌دهد رکورد مورد نظر از زمان بارگذاری تاکنون در دیتابیس تغییر کرده است.

مشاهده در آپارات یا یوتیوب

محتوای ویدیویی این صفحه در سایت قابل مشاهده است. اما اگر عادت دارید توی پلتفرم آپارات یا یوتیوب ویدیوها را مشاهده کنید، می‌توانید از دکمه‌های زیر استفاده کنید.

تماشای ویدیوی آموزش مدیریت همزمانی – Concurrency در EF Core در آپارات و یوتیوب

اشتراک‌گذاری با یک کلیک

با یک کلیک، محتوای این صفحه را در شبکه‌های اجتماعی، ایمیل یا پیام‌رسان‌های مورد علاقه‌تان به‌سرعت به اشتراک بگذارید.

اشتراک‌گذاری صفحه آموزش مدیریت همزمانی – Concurrency در EF Core در شبکه‌های اجتماعی

نظرات شما برای ما ارزشمند است

متاسفانه تاکنون پیامی برای این مطلب ثبت نشده است. شما اولین شخصی باشید که پیام می‌گذارد.

نظرات کاربران

فرم افزودن دیدگاه

با ارسال نظرات خود ما را در ایجاد محتوای بهتر کمک کنید.

با خدمات تهران آی تی آشنا شوید

تهران آی تی با افتخار خدمات زیر را ارائه می‌دهد.