יכולת סריאליזציה ובידוד של עסקאות

בדף הזה מתוארים התנגשות, יכולת סריאליזציה ובידוד של נתוני טרנזקציות. לדוגמאות קוד של עסקאות, קראו את המאמר עסקאות וכתיבה באצווה.

טרנזקציות ותחרות על נתונים

כדי שעסקה תצליח, המסמכים שאוחזרו על ידי פעולות הקריאה שלה חייבים להישאר ללא שינוי על ידי פעולות מחוץ לעסקה. אם פעולה אחרת מנסה לשנות את אחד מהמסמכים האלה, הפעולה הזו נכנסת למצב של תחרות על נתונים עם הטרנזקציה.

תחרות על נתונים
כששתי פעולות או יותר מתחרות על השליטה באותו מסמך. לדוגמה, יכול להיות שטרנזקציה אחת תדרוש שמסמך יישאר עקבי בזמן שפעולה בו-זמנית מנסה לעדכן את ערכי השדות של אותו מסמך.

Cloud Firestore פותרת את התחרות על הנתונים על ידי עיכוב או ביטול של אחת מהפעולות. ספריות הלקוח של Cloud Firestore מנסות באופן אוטומטי לבצע מחדש טרנזקציות שנכשלו בגלל תחרות על נתונים. אחרי מספר סופי של ניסיונות חוזרים, פעולת הטרנזקציה נכשלת ומוחזרת הודעת שגיאה:

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

ההתנהגות תלויה בסוג של בקרת הבו-זמניות כשמחליטים איזו פעולה תיכשל או תתעכב.

בקרת בו-זמניות

מצב בו-זמניות הוא אפשרות שניתן להגדיר במסד הנתונים. ‫Cloud Firestore תומך במצבי בו-זמניות הבאים:

  • ‫PESSIMISTIC: בקרות בו-זמניות פסימיות מניחות שסביר להניח שתהיה תחרות על נתונים. בטרנזקציות פסימיות, נעילות של מסד הנתונים מונעות מפעולות אחרות לשנות את הנתונים.

    בבקרת בו-זמניות פסימית, טרנזקציות נועלות את המסמכים שהן קוראות. נעילה של מסמך על ידי עסקה חוסמת עסקאות אחרות, כתיבה באצווה וכתיבה שאינה עסקאות מלשנות את המסמך הזה. טרנזקציה משחררת את נעילות המסמכים שלה בזמן האישור. הוא גם משחרר את הנעילות אם הזמן הקצוב לתפוגה חולף או אם הוא נכשל מסיבה כלשהי.

    כשטרנזקציה נועלת מסמך, פעולות כתיבה אחרות צריכות להמתין עד שהטרנזקציה תשחרר את הנעילה. העסקאות רוכשות את הנעילות שלהן בסדר כרונולוגי.

  • ‫OPTIMISTIC: בקרות בו-זמניות אופטימיות מניחות שאין סבירות גבוהה לתחרות על נתונים, או שלא יעיל להחזיק נעילות של מסד נתונים. בעסקאות אופטימיות לא משתמשים בנעילות של מסד הנתונים כדי לחסום פעולות אחרות מלשנות נתונים

    בבקרת בו-זמניות אופטימית, העסקה עוקבת אחרי כל המסמכים שאתם קוראים בתוך העסקה. העסקה משלימה את פעולות הכתיבה שלה רק אם אף אחד מהמסמכים האלה לא השתנה במהלך ביצוע העסקה. אם מסמך כלשהו השתנה, ה-transaction handler מנסה שוב לבצע את הטרנזקציה. אם העסקה לא מקבלת תוצאה נקייה אחרי כמה ניסיונות חוזרים, היא נכשלת בגלל תחרות על נתונים.

הגדרות ברירת המחדל של מצב בו-זמניות (concurrency)

ברירת המחדל במהדורת Standard היא PESSIMISTIC. ברירת המחדל במהדורת Enterprise היא OPTIMISTIC. עם זאת, ההתנהגות תלויה גם בסוג ספריית הלקוח:

  • ערכות ה-SDK לנייד ולאינטרנט משתמשות בבקרת בו-זמניות אופטימית. ערכות ה-SDK לנייד ולאינטרנט פועלות באופן עצמאי מההגדרה הזו, כי הן תמיד מדמות בו-זמניות אופטימית.
  • ספריות הלקוח של השרת משתמשות בבקרת בו-זמניות של הגדרת מסד הנתונים.

מצב צפייה בו-זמנית

מריצים את הפקודה gcloud firestore databases describe כדי לראות את מצב בו-זמניות בצד השרת של מסד הנתונים:

gcloud firestore databases describe \
  --project=PROJECT_ID \
  --database=DATABASE_ID

שינוי מצב בו-זמניות

מריצים את הפקודה gcloud firestore databases update כדי לשנות את מצב בו-זמניות בצד השרת של מסד הנתונים:

gcloud firestore databases update \
  --project=PROJECT_ID \
  --database=DATABASE_ID \
  --concurrency-mode=CONCURRENCY_MODE

כאשר:

  • ‫CONCURRENCY_MODE הוא PESSIMISTIC או OPTIMISTIC.
  • ‫PROJECT_ID הוא המזהה של פרויקט Google Cloud.
  • ‫DATABASE_ID הוא המזהה של מסד הנתונים ב-Cloud Firestore.

תחרות על נתונים בערכות ה-SDK לנייד או לאינטרנט

ערכות SDK לנייד ולאינטרנט מדמות עסקאות של בקרת בו-זמניות אופטימית באמצעות תנאים מוקדמים לכתיבה בגרסאות של מסמכים. ההדמיה הזו מתרחשת בלי קשר להגדרת מצב בו-זמניות של מסד הנתונים. ערכות ה-SDK לנייד ולאינטרנט לא משתמשות בתכונה עסקאות מובנות, כך שגם אם מצב בו-זמניות של מסד הנתונים מוגדר ל-PESSIMISTIC, לקוחות בנייד עדיין פועלים באופן אופטימי.

ערכות SDK לנייד או לאינטרנט משתמשות בבקרת בו-זמניות אופטימית, כי הן יכולות לפעול בסביבות עם זמן אחזור גבוה וחיבור לא אמין לרשת. נעילת מסמכים בסביבה עם זמן אחזור גבוה תגרום ליותר מדי כשלים של תחרות על נתונים.

תחרות על נתונים בספריות הלקוח של השרת

ספריות לקוח של שרת (C#‎,‏ Go, ‏ Java, ‏ Node.js, ‏ PHP, ‏ Python, ‏ Ruby) משתמשות בתכונה טרנזקציות מובנות. הטרנזקציות האלה משתמשות בהגדרה של מצב בו-זמניות ברמת מסד הנתונים, וברירת המחדל תלויה במהדורה:

  • כברירת מחדל, במהדורת Enterprise נעשה שימוש בבקרת בו-זמניות אופטימית כדי לתמוך בפעולות שסורקות אוספים שלמים. בקרות בו-זמניות אופטימיות עוזרות להימנע מפעולות סריקה שננעלות על מספר גדול של מסמכים.

  • במהדורת Standard נעשה שימוש בבקרת בו-זמניות פסימית, והיא מניחה זמן אחזור קצר וחיבור אמין למסד הנתונים.

בספריית לקוח של שרת עם חיבור בעל זמן אחזור גבוה, יכולות להיות בעיות של נעילה ותחרות על נתונים.

בידוד שניתן להמרה לסדרה

תחרות על נתונים בין טרנזקציות קשורה באופן הדוק לרמות הבידוד של מסד הנתונים. רמת הבידוד של מסד נתונים מתארת עד כמה המערכת מטפלת היטב בהתנגשויות בין פעולות בו-זמניות. ההתנגשות נובעת מהדרישות הבאות של מסד הנתונים:

  • כדי לבצע עסקאות, צריך נתונים מדויקים ועקביים.
  • כדי להשתמש במשאבים ביעילות, מסדי נתונים מבצעים פעולות בו-זמנית.

במערכות עם רמת בידוד נמוכה, פעולת קריאה בטרנזקציה עשויה לקרוא נתונים לא מדויקים משינויים שלא בוצעו בפעולה בו-זמנית.

בידוד שניתן להעברה (serializable) מגדיר את רמת הבידוד הגבוהה ביותר. בידוד מסוג Serializable אומר ש:

  • אפשר להניח שמסד הנתונים מבצע עסקאות בסדרות.
  • טרנזקציות לא מושפעות משינויים שלא בוצעו בפעולות בו-זמניות.

ההבטחה הזו חייבת להתקיים גם כשמסד הנתונים מבצע כמה טרנזקציות במקביל. מסד הנתונים חייב להטמיע בקרות בו-זמניות כדי לפתור התנגשויות שעלולות להפר את ההבטחה הזו.

‫Cloud Firestore מבטיח בידוד של עסקאות שניתן להמיר לסדרה. הטרנזקציות ב-Cloud Firestore עוברות סריאליזציה ובידוד לפי זמן ה-commit.

בידוד שמאפשר סריאליזציה לפי זמן השמירה

Cloud Firestore מקצה לכל עסקה זמן ביצוע שמייצג נקודה אחת בזמן. כש-Cloud Firestore מבצע את השינויים של טרנזקציה במסד הנתונים, אפשר להניח שכל פעולות הקריאה והכתיבה בטרנזקציה מתרחשות בדיוק בזמן הביצוע.

ביצוע עסקה בפועל דורש פרק זמן מסוים. הביצוע של טרנזקציה מתחיל לפני זמן האישור, והביצוע של כמה פעולות יכול לחפוף. ‫Cloud Firestore תומך בבידוד שמאפשר סריאליזציה ומבטיח ש:

  • ‫Cloud Firestore מבצע טרנזקציות לפי סדר זמן הביצוע.
  • Cloud Firestore מבודד עסקאות מפעולות בו-זמניות עם זמן אישור מאוחר יותר.

במקרה של מחלוקת על נתונים בין פעולות בו-זמניות, Cloud Firestore משתמש בבקרת בו-זמניות אופטימית ופסימית כדי לפתור את המחלוקת.

בידוד בתוך עסקה

רמת הבידוד של טרנזקציה חלה גם על פעולות כתיבה בתוך טרנזקציה. שאילתות וקריאות בתוך טרנזקציה לא רואות את התוצאות של כתיבות קודמות בתוך אותה טרנזקציה. גם אם משנים או מוחקים מסמך בטרנזקציה, כל קריאות המסמכים בטרנזקציה הזו מחזירות את גרסת המסמך בזמן ה-commit, לפני פעולות הכתיבה של הטרנזקציה. פעולות קריאה לא מחזירות כלום אם המסמך לא היה קיים באותו זמן.

בעיות שקשורות לתחרות על נתונים

מידע נוסף על מחלוקות לגבי נתונים ואיך לפתור אותן זמין בדף פתרון הבעיות.