عنوان:

‫سازگاری داده‌ها با قفل‌گذاری بدبینانه (Pessimistic Locking) در دات نت (.NET)


نویسنده: وحید نصیری
تاریخ: ۱۴۰۳/۱۲/۱۲ ۰۹:۲۹
آدرس: www.dntips.ir
هدف: قفل‌گذاری بدبینانه ابزاری حیاتی برای اطمینان از سازگاری داده‌ها، به‌ویژه در محیط‌هایی با همزمانی بالا (high concurrency) است. این روش با محدود کردن دسترسی به ردیف‌های خاص داده‌ها تا زمان تکمیل تراکنش (transaction)، از بروز تداخلات جلوگیری می‌کند و از یکپارچگی داده‌های شما محافظت می‌کند.

موارد استفاده: هنگامیکه اطمینان از سازگاری داده‌ها برای هر تراکنش بسیار مهم است. برای مثال:
  • تصور کنید یک پلتفرم تجارت الکترونیک (e-commerce) وجود دارد که در آن چندین کاربر به‌طور همزمان در حال ثبت سفارش برای یک محصول هستند. سیستم باید موجودی انبار را به‌صورت لحظه‌ای بررسی و به‌روزرسانی کند. اگر دو کاربر همزمان تلاش کنند آخرین واحد از همان محصول را خریداری کنند، بدون قفل‌گذاری بدبینانه، هر دو تراکنش ممکن است انجام شود و منجر به فروش بیش از حد محصول شود.
  • با استفاده از UPDLOCK همراه با NOWAIT، اطمینان حاصل می‌کنید که پس از شروع خرید آخرین کالا توسط یک کاربر، هیچ تراکنش دیگری نمی‌تواند به موجودی آن محصول دسترسی پیدا کرده و آن را تغییر دهد تا زمانی که تراکنش اول کامل شود. اگر قفل قابل دستیابی نباشد (مثلاً شخص دیگری در حال پردازش سفارش است)، تراکنش دوم به‌سرعت با شکست مواجه می‌شود و از مشکل فروش بیش از حد جلوگیری می‌کند.
  • عدم به‌روزرسانی‌های ناقص: شمارش موجودی فقط یک بار در هر تراکنش به‌روزرسانی می‌شود و از بروز ناهماهنگی‌ها جلوگیری می‌کند.
  • عدم تغییرات ناخواسته: هیچ تراکنش دیگری نمی‌تواند موجودی آن محصول را در طول فرآیند سفارش تغییر دهد.
  • این روش برای موارد زیر ایده‌آل است:
    • به‌روزرسانی‌های حیاتی: جایی که سازگاری داده‌ها ضروری است، مانند به‌روزرسانی سطوح موجودی محصول در طول فرآیند پرداخت.
    • مکانیسم‌های شکست سریع (Fail-Fast Mechanisms): برای جلوگیری از هنگ دائمی برنامه شما هنگام تلاش برای به‌دست آوردن قفل.
    • محیط‌های با همزمانی بالا: جایی که کاربران زیادی ممکن است به‌طور همزمان تلاش کنند داده‌های مشابه را به‌روزرسانی کنند، مانند سیستم مدیریت سفارش در طول فروش‌های ویژه.

پیاده‌سازی: از UPDLOCK با NOWAIT در MSSQL از طریق پرس و جوهای SQL خام در EF Core استفاده می‌شود و از FOR UPDATE NOWAIT در Postgrest استفاده می‌شود.

مزایا:
  • یکپارچگی داده‌ها: اطمینان می‌دهد که فقط یک تراکنش می‌تواند یک ردیف خاص را در یک زمان تغییر دهد و از خرابی داده‌ها یا حالت‌های ناسازگار جلوگیری می‌کند.
  • رفتار شکست سریع: با NOWAIT، اگر قفل نتواند بلافاصله به‌دست آید، عملیات با شکست مواجه می‌شود و از تأخیرهای غیرضروری جلوگیری می‌کند و عملکرد بهینه را حفظ می‌کند.
  • جلوگیری از تداخل: به‌ویژه زمانی مفید است که چندین کاربر یا سیستم تلاش می‌کنند همزمان رکوردهای مشابه را به‌روزرسانی کنند و از شرایط مسابقه (race conditions) جلوگیری می‌کند.
  • کنترل بهتر بر قفل‌ها: شما کنترل دقیق‌تری بر ردیف‌هایی که قفل می‌شوند دارید و از قفل کردن غیرضروری رکوردهای نامرتبط جلوگیری می‌کنید.
  • کاهش خطر خواندن‌های کثیف (Dirty Reads): تضمین می‌کند که هیچ تراکنش دیگری نمی‌تواند داده‌ها را در حین انجام تراکنش شما بخواند یا تغییر دهد.

چالش‌ها: نگرانی‌های مربوط به مقیاس‌پذیری در محیط‌های با همزمانی بسیار بالا.
  • شکست‌های مکرر قفل می‌تواند منجر به تلاش‌های مجدد شود و عملکرد را تحت تأثیر قرار دهد.
  • منطق تلاش مجدد پیچیده مورد نیاز است.
  • خطر قفل‌شدگی (Deadlock) یا گرسنگی قفل (lock starvation).


مشاهده مطلب اصلی