התנגשות נתונים בעסקאות

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

טרנזקציות ועימות נתונים

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

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

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

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

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

אמצעי בקרה לבו-זמניות

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

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

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

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

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

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

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

ערך ברירת המחדל במהדורת 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

where:

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

התנגשות נתונים בערכות SDK לניידים ולאתרים

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

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

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

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

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

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

בידוד ניתן לסריאליזציה

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

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

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

בידוד ניתן לסדר מגדיר את רמת הבידוד הגבוהה ביותר. בידוד ניתן לסדר פירושו:

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

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

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

בידוד ניתן לסדר לפי זמן ביצוע (commit)

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

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

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

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

בידוד בתוך טרנזקציה

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

בעיות שקשורות להתנגשות נתונים

מידע נוסף על התנגשות נתונים ועל פתרון בעיות מופיע בדף לפתרון בעיות.