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