בדף הזה מתוארים התנגשות נתונים טרנזקציונלית, אפשרות סדרתית ובידוד. דוגמאות קוד של טרנזקציות זמינות במאמר בנושא טרנזקציות וכתיבות באצווה.
טרנזקציות ועימות נתונים
כדי שעסקה תצליח, המסמכים שאוחזרו על ידי פעולות הקריאה שלה לא יכולים להשתנות על ידי פעולות מחוץ לעסקה. אם פעולה אחרת מנסה לשנות אחד מהמסמכים האלה, הפעולה הזו נכנסת למצב של התנגשות נתונים עם העסקה.
- התנגשות נתונים
- כששתי פעולות או יותר מתחרות על השליטה באותו מסמך. לדוגמה, יכול להיות שטרנזקציה אחת תדרוש שהמסמך יישאר עקבי, בזמן שמבצעים פעולה בו-זמנית שמנסה לעדכן את ערכי השדות של המסמך.
Cloud Firestore פותר את הבעיה של התנגשות נתונים על ידי עיכוב של אחת מהפעולות או ביטול שלה. Cloud Firestore ספריות הלקוח מנסות אוטומטית לבצע שוב טרנזקציות שנכשלות בגלל התנגשות נתונים. אחרי מספר סופי של ניסיונות חוזרים, פעולת העסקה נכשלת ומוחזרת הודעת שגיאה:
ABORTED: Too much contention on these documents. Please try again.
כשמחליטים איזו פעולה להפסיק או לעכב, ההתנהגות תלויה בסוג של ספריית הלקוח.
אפשר להגדיר את Cloud Firestore במצב מקבילי: PESSIMISTIC
או OPTIMISTIC
. ערך ברירת המחדל של מהדורת Standard הוא PESSIMISTIC
, ושל מהדורת Enterprise הוא OPTIMISTIC
. מומלץ להשתמש ב-PESSIMISTIC
. ערכות ה-SDK לנייד ולאינטרנט פועלות באופן עצמאי מההגדרה הזו, כי הן תמיד מדמות מקביליות אופטימית.
מערכות ה-SDK לנייד ול-Web משתמשות באמצעי בקרה של concurrency אופטימי.
ספריות הלקוח של השרת משתמשות באמצעי בקרה של מקביליות פסימית.
התנגשות נתונים בערכות ה-SDK לניידים ולאתרים
ערכות SDK לנייד ולאינטרנט מדמות טרנזקציות של אופטימיזציה של מקביליות באמצעות תנאים מוקדמים לכתיבה בגרסאות של מסמכים. האמולציה הזו מתרחשת ללא קשר להגדרת מצב הגישה בו-זמנית של מסד הנתונים. ערכות ה-SDK לנייד ולאינטרנט לא משתמשות בתכונה built-in transactions, ולכן גם אם מצב הגישה בו-זמנית למסד הנתונים מוגדר ל-PESSIMISTIC
, לקוחות ניידים עדיין מתנהגים בצורה אופטימית.
- אמצעים אופטימיים לבקרת בו-זמניות
- בהנחה שאין סיכוי גבוה להתנגשות נתונים או שלא יעיל להחזיק נעילות של מסד הנתונים. עסקאות אופטימיות לא משתמשות בנעילות של מסדי נתונים כדי לחסום פעולות אחרות שמשנות נתונים.
ערכות SDK לנייד ולאינטרנט משתמשות באמצעי בקרה אופטימיים של פעולות מקבילות, כי הן יכולות לפעול בסביבות עם חביון גבוה וחיבור רשת לא אמין. נעילת מסמכים בסביבה עם זמן אחזור גבוה תגרום ליותר מדי כשלים בגישה לנתונים.
ב-SDK לנייד או לאתר, העסקה עוקבת אחרי כל המסמכים שקוראים בתוך העסקה. פעולות הכתיבה של העסקה יושלמו רק אם אף אחד מהמסמכים האלה לא השתנה במהלך ביצוע העסקה. אם מסמך כלשהו השתנה, המטפל בעסקאות מנסה שוב לבצע את העסקה. אם העסקה לא יכולה להניב תוצאה נקייה אחרי כמה ניסיונות חוזרים, העסקה נכשלת בגלל התנגשות נתונים.
התנגשות נתונים בספריות הלקוח של השרת
ספריות לקוח של שרת (C#, Go, Java, Node.js, PHP, Python, Ruby) משתמשות בתכונה built-in transactions, שמטמיעה כברירת מחדל אמצעי בקרה פסימיים של פעולות בו-זמניות. העסקאות האלה מתבצעות בהתאם להגדרה של מצב הגישה בו-זמנית ברמת מסד הנתונים (בדרך כלל PESSIMISTIC
) ומשתמשות בנעילות של מסמכים כדי למנוע כתיבות סותרות.
- אמצעים פסימיים לשליטה בבו-זמניות
- בהנחה שסביר להניח שיהיו התנגשויות בנתונים. בטרנזקציות פסימיות נעשה שימוש בנעילות של מסדי נתונים כדי למנוע מפעולות אחרות לשנות את הנתונים.
ספריות לקוח של שרתים משתמשות באמצעי בקרה של מקביליות פסימית, כי הן מניחות שיש זמן אחזור נמוך וחיבור אמין למסד הנתונים.
בספריות הלקוח של השרת, טרנזקציות מציבות נעילות על המסמכים שהן קוראות. נעילה של מסמך על ידי טרנזקציה חוסמת טרנזקציות אחרות, כתיבות באצווה וכתיבות לא טרנזקציונליות מלשנות את המסמך הזה. נעילות המסמכים של טרנזקציה משתחררות בזמן ביצוע הטרנזקציה. הוא גם מבטל את הנעילות שלו אם הוא לא מסיים את הפעולה בזמן או אם הוא נכשל מסיבה כלשהי.
כשעסקה נועלת מסמך, פעולות כתיבה אחרות צריכות להמתין עד שהעסקה תשחרר את הנעילה. הנעילות של העסקאות מתבצעות לפי הסדר הכרונולוגי.
בידוד סריאלי
התחרות על נתונים בין טרנזקציות קשורה קשר הדוק לרמות הבידוד של מסד הנתונים. רמת הבידוד של מסד נתונים מתארת את היכולת של המערכת לטפל בקונפליקטים בין פעולות מקבילות. הבעיה נובעת מהדרישות הבאות של מסד הנתונים:
- כדי שהדיווח על עסקאות יהיה מדויק, הנתונים צריכים להיות מדויקים ועקביים.
- כדי להשתמש במשאבים בצורה יעילה, מסדי נתונים מבצעים פעולות במקביל.
במערכות עם רמת בידוד נמוכה, פעולת קריאה בתוך טרנזקציה עשויה לקרוא נתונים לא מדויקים משינויים שלא בוצעו בפעולה מקבילה.
בידוד ניתן לסדר מגדיר את רמת הבידוד הגבוהה ביותר. בידוד ניתן לסריאליזציה פירושו:
- אפשר להניח שמסד הנתונים מבצע עסקאות בסדרה.
- עסקאות לא מושפעות משינויים שלא בוצעו בפעולות מקבילות.
ההבטחה הזו צריכה להתקיים גם בזמן שמסד הנתונים מבצע כמה טרנזקציות במקביל. במסד הנתונים צריך להטמיע אמצעי בקרה של פעולות מקבילות כדי לפתור קונפליקטים שעלולים לפגוע בהבטחה הזו.
Cloud Firestore מבטיח בידוד של טרנזקציות שניתן לסדר אותן בסדרות. העסקאות ב-Cloud Firestore עוברות סריאליזציה ומבודדות לפי זמן השמירה.
בידוד ניתן לסריאליזציה לפי זמן ביצוע
Cloud Firestore מקצה לכל טרנזקציה זמן אישור שמייצג נקודה אחת בזמן. כש-Cloud Firestore מבצע את השינויים של טרנזקציה במסד הנתונים, אפשר להניח שכל פעולות הקריאה והכתיבה בטרנזקציה מתבצעות בדיוק בזמן השמירה.
ביצוע בפועל של עסקה דורש פרק זמן מסוים. ההרצה של טרנזקציה מתחילה לפני זמן השמירה, וההרצה של כמה פעולות עשויה לחפוף. Cloud Firestore תומך בבידוד שניתן לסדר בסדרות ומבטיח את הדברים הבאים:
- Cloud Firestore מבצעת את העסקאות לפי סדר הזמן של ביצוע השינויים.
- Cloud Firestore מבודד עסקאות מפעולות מקבילות עם זמן אישור מאוחר יותר.
במקרה של מחלוקת על נתונים בין פעולות מקבילות, Cloud Firestore משתמש בבקרה אופטימית ופסימית של פעולות מקבילות כדי לפתור את המחלוקת.
בידוד בתוך טרנזקציה
רמת הבידוד של טרנזקציה חלה גם על פעולות כתיבה בתוך טרנזקציה. שאילתות וקריאות בתוך טרנזקציה לא רואות את התוצאות של פעולות כתיבה קודמות בתוך אותה טרנזקציה. גם אם משנים או מוחקים מסמך בתוך עסקה, כל פעולות הקריאה של המסמך בעסקה מחזירות את גרסת המסמך בזמן השמירה, לפני פעולות הכתיבה של העסקה. פעולות קריאה לא מחזירות כלום אם המסמך לא היה קיים בזמן הקריאה.
בעיות שקשורות להתנגשות נתונים
מידע נוסף על התנגשות נתונים ועל פתרון בעיות מופיע בדף לפתרון בעיות.