قابلیت سریال سازی و جداسازی تراکنش ها

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

تراکنش‌ها و تداخل داده‌ها

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

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

Cloud Firestore با به تأخیر انداختن یا شکست دادن یکی از عملیات‌ها، تداخل داده‌ها را حل می‌کند. کتابخانه‌های کلاینت Cloud Firestore به طور خودکار تراکنش‌هایی را که به دلیل تداخل داده‌ها شکست می‌خورند، دوباره امتحان می‌کنند. پس از تعداد محدودی تلاش مجدد، عملیات تراکنش شکست می‌خورد و یک پیام خطا برمی‌گرداند:

ABORTED: Too much contention on these documents. Please try again.

هنگام تصمیم‌گیری در مورد اینکه کدام عملیات باید ناموفق باشد یا به تأخیر بیفتد، رفتار به نوع کتابخانه کلاینت بستگی دارد.

Cloud Firestore PESSIMISTIC با حالت همزمانی پیکربندی کرد: PESSIMISTIC یا OPTIMISTIC . حالت پیش‌فرض برای نسخه استاندارد PESSIMISTIC است در حالی که نسخه سازمانی OPTIMISTIC توصیه می‌شود. SDK های موبایل و وب مستقل از این تنظیم رفتار می‌کنند زیرا همیشه همزمانی خوش‌بینانه را شبیه‌سازی می‌کنند.

  • SDK های موبایل/وب از کنترل‌های همزمانی خوش‌بینانه استفاده می‌کنند.

  • کتابخانه‌های کلاینت سرور از کنترل‌های همزمانی بدبینانه استفاده می‌کنند.

تداخل داده‌ها در SDKهای موبایل/وب

SDK های موبایل و وب، تراکنش‌های همزمانی خوش‌بینانه را با استفاده از پیش‌شرط‌های نوشتن روی نسخه‌های سند شبیه‌سازی می‌کنند. این شبیه‌سازی صرف نظر از تنظیمات حالت همزمانی پایگاه داده رخ می‌دهد. SDK های موبایل و وب از ویژگی تراکنش‌های داخلی استفاده نمی‌کنند، بنابراین حتی اگر حالت همزمانی پایگاه داده برای PESSIMISTIC پیکربندی شده باشد، کلاینت‌های موبایل همچنان خوش‌بینانه رفتار می‌کنند.

کنترل‌های همزمانی خوش‌بینانه
بر اساس این فرض که احتمال تداخل داده‌ها وجود ندارد یا اینکه نگه داشتن قفل‌های پایگاه داده کارآمد نیست. تراکنش‌های خوش‌بینانه از قفل‌های پایگاه داده برای جلوگیری از تغییر داده‌ها توسط سایر عملیات استفاده نمی‌کنند.

SDK های موبایل/وب از کنترل‌های همزمانی خوش‌بینانه استفاده می‌کنند، زیرا می‌توانند در محیط‌هایی با تأخیر بالا و اتصال شبکه غیرقابل اعتماد کار کنند. قفل کردن اسناد در یک محیط با تأخیر بالا باعث خرابی‌های زیادی در رقابت داده‌ها می‌شود.

در SDK های موبایل/وب، یک تراکنش تمام اسنادی را که شما درون تراکنش می‌خوانید، ردیابی می‌کند. تراکنش عملیات نوشتن خود را تنها در صورتی تکمیل می‌کند که هیچ یک از آن اسناد در طول اجرای تراکنش تغییر نکرده باشند. اگر هر سندی تغییر کرده باشد، کنترل‌کننده تراکنش، تراکنش را دوباره امتحان می‌کند. اگر تراکنش پس از چند تلاش مجدد نتواند نتیجه‌ای تمیز دریافت کند، تراکنش به دلیل تداخل داده‌ها با شکست مواجه می‌شود.

تداخل داده‌ها در کتابخانه‌های کلاینت سرور

کتابخانه‌های کلاینت سرور (C#، Go، Java، Node.js، PHP، Python، Ruby) از ویژگی تراکنش‌های داخلی استفاده می‌کنند که به طور پیش‌فرض کنترل‌های همزمانی بدبینانه را پیاده‌سازی می‌کند. این تراکنش‌ها از تنظیمات حالت همزمانی سطح پایگاه داده (معمولاً PESSIMISTIC ) پیروی می‌کنند و از قفل‌های سند برای جلوگیری از نوشتن‌های متناقض استفاده می‌کنند.

کنترل‌های همزمانی بدبینانه
بر اساس این فرض که احتمال تداخل داده‌ها وجود دارد. تراکنش‌های بدبینانه از قفل‌های پایگاه داده برای جلوگیری از تغییر داده‌ها توسط سایر عملیات استفاده می‌کنند.

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

در کتابخانه‌های کلاینت سرور، تراکنش‌ها قفل‌هایی را روی اسنادی که می‌خوانند قرار می‌دهند. قفل یک تراکنش روی یک سند، مانع از تغییر آن سند توسط سایر تراکنش‌ها، نوشتن‌های دسته‌ای و نوشتن‌های غیر تراکنشی می‌شود. یک تراکنش قفل‌های سند خود را در زمان انجام تراکنش آزاد می‌کند. همچنین اگر به هر دلیلی مهلتش تمام شود یا شکست بخورد، قفل‌های خود را آزاد می‌کند.

وقتی یک تراکنش، سندی را قفل می‌کند، سایر عملیات نوشتن باید منتظر بمانند تا تراکنش قفل خود را آزاد کند. تراکنش‌ها قفل‌های خود را به ترتیب زمانی دریافت می‌کنند.

ایزولاسیون قابل سریال‌سازی

اختلاف داده‌ها بین تراکنش‌ها ارتباط نزدیکی با سطوح ایزولاسیون پایگاه داده دارد. سطح ایزولاسیون یک پایگاه داده، میزان عملکرد سیستم در مدیریت تداخلات بین عملیات همزمان را نشان می‌دهد. تداخل از الزامات پایگاه داده زیر ناشی می‌شود:

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

در سیستم‌هایی با سطح ایزولاسیون پایین، یک عملیات خواندن درون یک تراکنش ممکن است داده‌های نادرستی را از تغییرات ثبت نشده در یک عملیات همزمان بخواند.

ایزولاسیون سریالی شدنی، بالاترین سطح ایزولاسیون را تعریف می‌کند. ایزولاسیون سریالی شدنی به این معنی است که:

  • می‌توانید فرض کنید که پایگاه داده تراکنش‌ها را به صورت سری اجرا می‌کند.
  • تراکنش‌ها تحت تأثیر تغییرات قطعی نشده در عملیات همزمان قرار نمی‌گیرند.

این ضمانت باید حتی در حالی که پایگاه داده چندین تراکنش را به صورت موازی اجرا می‌کند، پابرجا بماند. پایگاه داده باید کنترل‌های همزمانی را برای حل تداخل‌هایی که این ضمانت را نقض می‌کنند، پیاده‌سازی کند.

Cloud Firestore جداسازی تراکنش‌ها با قابلیت سریال‌سازی را تضمین می‌کند. تراکنش‌ها در Cloud Firestore بر اساس زمان ثبت، سریال‌سازی و ایزوله می‌شوند.

جداسازی قابل سریال‌سازی بر اساس زمان کامیت

Cloud Firestore به هر تراکنش یک زمان ثبت (commit time) اختصاص می‌دهد که نشان‌دهنده یک نقطه زمانی واحد است. وقتی Cloud Firestore تغییرات یک تراکنش را در پایگاه داده ثبت می‌کند، می‌توانید فرض کنید که تمام خواندن‌ها و نوشتن‌های درون تراکنش دقیقاً در زمان ثبت انجام می‌شود.

اجرای واقعی یک تراکنش به مدتی زمان نیاز دارد. اجرای یک تراکنش قبل از زمان تایید شروع می‌شود و اجرای چندین عملیات ممکن است با هم همپوشانی داشته باشند. Cloud Firestore از جداسازی سریالی پشتیبانی می‌کند و موارد زیر را تضمین می‌کند:

  • Cloud Firestore تراکنش‌ها را به ترتیب زمان انجام، انجام می‌دهد.
  • Cloud Firestore تراکنش‌ها را از عملیات همزمان با زمان کامیت دیرتر جدا می‌کند.

در مورد اختلاف داده‌ها بین عملیات همزمان، Cloud Firestore از کنترل‌های همزمانی خوش‌بینانه و بدبینانه برای حل اختلاف استفاده می‌کند.

جداسازی در یک تراکنش

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

مشکلات مربوط به تداخل داده‌ها

برای اطلاعات بیشتر در مورد تداخل داده‌ها و نحوه رفع آنها، به صفحه عیب‌یابی مراجعه کنید.