این صفحه جدال داده های تراکنش، سریال پذیری و جداسازی را شرح می دهد. برای نمونه کد تراکنش، تراکنشها و نوشتههای دستهای را ببینید.
معاملات و جدال داده ها
برای موفقیت یک تراکنش، اسناد بازیابی شده توسط عملیات خواندن آن باید توسط عملیات خارج از تراکنش اصلاح نشده باقی بمانند. اگر عملیات دیگری بخواهد یکی از آن اسناد را تغییر دهد، آن عملیات وارد وضعیت اختلاف داده با تراکنش می شود.
- جدال داده ها
- هنگامی که دو یا چند عملیات برای کنترل یک سند با هم رقابت می کنند. به عنوان مثال، ممکن است یک تراکنش نیاز داشته باشد که یک سند ثابت بماند در حالی که یک عملیات همزمان سعی می کند مقادیر فیلد آن سند را به روز کند.
Cloud Firestore با تأخیر یا عدم موفقیت یکی از عملیات، اختلافات داده را حل می کند. کتابخانه های سرویس گیرنده Cloud Firestore به طور خودکار تراکنش هایی را که به دلیل اختلاف داده ها با شکست مواجه می شوند، دوباره امتحان می کنند. پس از تعداد محدودی از تلاش های مجدد، عملیات تراکنش با شکست مواجه می شود و یک پیام خطا برمی گرداند:
ABORTED: Too much contention on these documents. Please try again.
زمانی که تصمیم می گیرید کدام عملیات با شکست مواجه شود یا به تاخیر بیفتد، رفتار بستگی به نوع کتابخانه مشتری دارد.
SDK های موبایل/وب از کنترل های همزمان خوش بینانه استفاده می کنند.
کتابخانه های سرویس گیرنده از کنترل های همزمان بدبینانه استفاده می کنند.
جدال داده در SDKهای موبایل/وب
کیتهای توسعه نرمافزار موبایل/وب (پلتفرمهای اپل، اندروید، وب، سی++) از کنترلهای همزمانی خوشبینانه برای حل اختلافات دادهها استفاده میکنند.
- کنترل های همزمان خوش بینانه
- بر اساس این فرض که جدال داده محتمل نیست یا اینکه نگه داشتن قفل های پایگاه داده کارآمد نیست. تراکنش های خوش بینانه از قفل های پایگاه داده برای مسدود کردن سایر عملیات ها از تغییر داده ها استفاده نمی کنند.
SDKهای موبایل/وب از کنترلهای همزمان خوشبینانه استفاده میکنند، زیرا میتوانند در محیطهایی با تأخیر بالا و اتصال شبکه غیرقابل اعتماد کار کنند. قفل کردن اسناد در یک محیط با تأخیر بالا باعث شکست بیش از حد اختلاف داده ها می شود.
در SDK های موبایل/وب، تراکنش تمام اسنادی را که در داخل تراکنش می خوانید، ردیابی می کند. تراکنش فقط در صورتی عملیات نوشتن خود را کامل می کند که هیچ یک از آن اسناد در طول اجرای تراکنش تغییر نکند. اگر سندی تغییر کرد، کنترل کننده تراکنش تراکنش را دوباره امتحان می کند. اگر تراکنش نتواند پس از چند بار تلاش مجدد به یک نتیجه تمیز دست یابد، تراکنش به دلیل اختلاف داده ها با شکست مواجه می شود.
جدال داده ها در کتابخانه های سرویس گیرنده
کتابخانههای سرویس گیرنده سرور (C#، Go، Java، Node.js، PHP، Python، Ruby) از کنترلهای بدبینانه همزمانی استفاده میکنند.
- کنترل های همزمان بدبینانه
- بر اساس این فرض که اختلاف داده ها محتمل است. تراکنش های بدبینانه از قفل های پایگاه داده برای جلوگیری از تغییر داده ها توسط سایر عملیات ها استفاده می کنند.
کتابخانه های سرویس گیرنده از کنترل های همزمان بدبینانه استفاده می کنند، زیرا تأخیر کم و اتصال قابل اعتماد به پایگاه داده را فرض می کنند.
در کتابخانه های سرویس گیرنده سرور، تراکنش ها روی اسنادی که می خوانند قفل می کنند. قفل تراکنش روی یک سند، سایر تراکنشها، نوشتههای دستهای و نوشتههای غیرمعامله را از تغییر آن سند مسدود میکند. یک تراکنش قفل های اسناد خود را در زمان تعهد آزاد می کند. همچنین در صورت اتمام یا خرابی به هر دلیلی قفل های خود را آزاد می کند.
هنگامی که یک تراکنش یک سند را قفل می کند، سایر عملیات نوشتن باید منتظر بمانند تا تراکنش قفل خود را آزاد کند. معاملات به ترتیب زمانی قفل خود را به دست می آورند.
جداسازی سریالی
جدال داده ها بین تراکنش ها ارتباط نزدیکی با سطوح جداسازی پایگاه داده دارد. سطح ایزوله یک پایگاه داده توصیف می کند که سیستم چگونه تضاد بین عملیات همزمان را مدیریت می کند. تضاد ناشی از الزامات پایگاه داده زیر است:
- تراکنش ها به داده های دقیق و ثابت نیاز دارند.
- برای استفاده بهینه از منابع، پایگاه های داده عملیات را همزمان اجرا می کنند.
در سیستم هایی با سطح ایزوله پایین، یک عملیات خواندن در یک تراکنش ممکن است داده های نادرست را از تغییرات غیرمتعهد در یک عملیات همزمان بخواند.
جداسازی سریالی بالاترین سطح ایزوله را تعریف می کند. جداسازی سریالی به این معنی است که:
- شما می توانید فرض کنید که پایگاه داده تراکنش ها را به صورت سری اجرا می کند.
- معاملات تحت تأثیر تغییرات غیرمتعهد در عملیات همزمان قرار نمی گیرند.
این ضمانت باید حتی زمانی که پایگاه داده چندین تراکنش را به صورت موازی انجام می دهد، حفظ شود. پایگاه داده باید کنترلهای همزمانی را برای حل تعارضاتی که این تضمین را از بین میبرد، اجرا کند.
Cloud Firestore جداسازی سریالی تراکنش ها را تضمین می کند. تراکنش ها در Cloud Firestore به صورت سریالی و ایزوله شده توسط زمان تعهد انجام می شود.
جداسازی سریال با زمان ارتکاب
Cloud Firestore به هر تراکنش یک زمان تعهد اختصاص می دهد که نشان دهنده یک نقطه در زمان است. هنگامی که Cloud Firestore تغییرات یک تراکنش را در پایگاه داده انجام می دهد، می توانید فرض کنید که تمام خواندن و نوشتن در تراکنش دقیقاً در زمان commit انجام می شود.
اجرای واقعی یک تراکنش به مدتی زمان نیاز دارد. اجرای یک تراکنش قبل از زمان تعهد شروع می شود و ممکن است اجرای چندین عملیات با هم تداخل داشته باشند. Cloud Firestore از جداسازی سریال پذیر حمایت می کند و تضمین می کند که:
- Cloud Firestore تراکنش ها را به ترتیب زمان تعهد انجام می دهد.
- Cloud Firestore تراکنش ها را از عملیات همزمان با زمان تعهد بعدی جدا می کند.
در مورد اختلاف داده ها بین عملیات همزمان، Cloud Firestore از کنترل های همزمانی خوش بینانه و بدبینانه برای حل اختلاف استفاده می کند.
انزوا در یک معامله
جداسازی تراکنش برای عملیات نوشتن در یک تراکنش نیز کاربرد دارد. پرس و جوها و خوانده های داخل یک تراکنش، نتایج نوشته های قبلی را در داخل آن تراکنش نمی بینند. حتی اگر سندی را در یک تراکنش تغییر دهید یا حذف کنید، تمام اسناد خوانده شده در آن تراکنش، نسخه سند را در زمان تعهد، قبل از عملیات نوشتن تراکنش، برمیگردانند. اگر سند در آن زمان وجود نداشته باشد، عملیات خواندن هیچ چیزی را باز نمیگرداند.
مسائل مربوط به جدال داده ها
برای اطلاعات بیشتر در مورد اختلاف داده ها و نحوه حل آنها صفحه عیب یابی را بررسی کنید.