עסקה היא פעולה או קבוצה של פעולות שמובטח שהן אטומיות, כלומר אף פעם לא מוחלות רק חלק מהפעולות בעסקה. כל הפעולות בעסקה מוחלות, או שאף אחת מהן לא מוחלת. משך הזמן המקסימלי של העסקאות הוא 60 שניות, עם זמן תפוגה של 10 שניות בלי פעילות אחרי 30 שניות.
באמצעות NDB asynchronous API,
אפליקציה יכולה לנהל כמה
טרנזקציות בו-זמנית אם הן בלתי תלויות.
ממשק ה-API הסינכרוני מציע API פשוט יותר באמצעות ה-decorator @ndb.transactional().
הפונקציה המקושטת מופעלת בהקשר של העסקה.
אם העסקה מתנגשת עם עסקה אחרת, היא נכשלת. NDB מנסה לבצע שוב באופן אוטומטי עסקאות שנכשלו כמה פעמים.
יכול להיות שהפונקציה תיקרא כמה פעמים אם המערכת תנסה לבצע את העסקה שוב. יש מגבלה (ברירת מחדל היא 3) על מספר הניסיונות החוזרים. אם העסקה עדיין לא מצליחה, NDB מעלה את TransactionFailedError. אפשר לשנות את מספר הניסיונות החוזרים על ידי העברת retries=N אל העיטור transactional().
מספר הניסיונות החוזרים 0 מציין שהמערכת תנסה לבצע את העסקה פעם אחת, אבל לא תנסה שוב אם היא תיכשל. מספר הניסיונות החוזרים N מציין שהמערכת תנסה לבצע את העסקה בסך הכול N+1 פעמים. דוגמה:
בעסקאות, מותרות רק שאילתות של צאצאים. כברירת מחדל, טרנזקציה יכולה לפעול רק עם ישויות באותה קבוצת ישויות (ישויות שהמפתחות שלהן כוללים את אותה ישות אב).
אפשר לציין עסקאות חוצות קבוצות (XG) (שמאפשרות עד 25 קבוצות ישויות) על ידי העברת xg=True:
עסקאות בין קבוצות פועלות על פני כמה קבוצות ישויות, והן מתנהגות כמו עסקאות של קבוצה אחת, אבל הן לא נכשלות אם הקוד מנסה לעדכן ישויות מיותר מקבוצת ישויות אחת.
אם הפונקציה מעלה חריגה, העסקה מבוטלת באופן מיידי ו-NDB מעלה מחדש את החריגה כדי שהקוד שקורא לה יראה אותה.
אפשר לאלץ עסקה להיכשל בלי להציג הודעה על כך על ידי העלאת החריגה ndb.Rollback (בקשה להפעלת פונקציה מחזירה None במקרה הזה). אין מנגנון שמאלץ ניסיון חוזר.
יכול להיות שיש לכם פונקציה שאתם לא רוצים להפעיל תמיד בעסקה. במקום להוסיף את @ndb.transactional לפונקציה כזו, מעבירים אותה כפונקציית קריאה חוזרת ל-ndb.transaction().
כדי לבדוק אם קוד מסוים פועל בתוך טרנזקציה, משתמשים בפונקציה in_transaction().
אפשר לציין איך פונקציה 'טרנזקציונלית' צריכה להתנהג אם היא מופעלת על ידי קוד שכבר נמצא בטרנזקציה. הדקורטור @ndb.non_transactional מציין שפונקציה לא צריכה לפעול בטרנזקציה. אם היא נקראת בטרנזקציה, היא פועלת מחוץ לטרנזקציה. הדקורטור @ndb.transactional והפונקציה ndb.transaction מקבלים ארגומנט של מילת המפתח propagation. לדוגמה, אם פונקציה צריכה להתחיל טרנזקציה חדשה ועצמאית, צריך להוסיף לה את העיטור הבא:
סוגי ההפצה מופיעים עם אפשרויות ההקשר ואפשרויות העסקה האחרות.
ההתנהגות של העסקאות וההתנהגות של NDB בנוגע לשמירה במטמון יכולות לגרום לבלבול אם לא יודעים מה קורה. אם משנים ישות בתוך טרנזקציה אבל עדיין לא מבצעים commit של הטרנזקציה, במטמון ההקשר של NDB יש את הערך ששונה, אבל במאגר הנתונים הבסיסי עדיין יש את הערך שלא שונה.
הוספה לתור של משימות טרנזקציונליות
אפשר להוסיף משימה לתור כחלק מטרנזקציית Datastore, כך שהמשימה תתווסף לתור רק אם הטרנזקציה תאושר בהצלחה. אם העסקה לא תאושר, המשימה לא תתווסף לתור. אם העסקה תאושר, המשימה תתווסף לתור. אחרי שהמשימה מתווספת לתור, היא לא מבוצעת באופן מיידי, ולכן היא לא אטומית לעסקה. עם זאת, אחרי שהמשימה מתווספת לתור, המערכת תנסה לבצע אותה שוב ושוב עד שהיא תצליח. ההגדרה הזו חלה על כל משימה שמוכנסת לתור במהלך פונקציה עם קישוט.
משימות טרנזקציונליות שימושיות כי הן מאפשרות לכם לשלב פעולות שאינן Datastore בטרנזקציה שתלויה בהצלחת הטרנזקציה (למשל, שליחת אימייל לאישור רכישה). אפשר גם לקשר פעולות ב-Datastore לעסקה, למשל לבצע שינויים בקבוצות ישויות מחוץ לעסקה רק אם העסקה מצליחה.
אפליקציה לא יכולה להוסיף יותר מחמישה משימות טרנזקציונליות לתורי משימות במהלך טרנזקציה אחת. למשימות טרנזקציונליות אסור להכיל שמות שהמשתמש הגדיר.