שחזור טעינה מ-SQL Server ל-Oracle לאחר נפילת ה-VPN
VPN שנפל משאיר את הקורא ללא ודאות אם ה-commit ב-Oracle הושלם. מזהה אצווה עמיד מאפשר לענות על חילוץ, החלה והתאמה אחד אחרי השני.
העברה בין מסדי נתונים מתה כשהחיבור ל-VPN נופל, ו«הרץ שוב» אינו תוכנית התאוששות. חילוץ המקור עשוי להיות שלם, היעד עשוי כבר לבצע commit, או שהתשובה פשוט אבדה בדרך חזרה. שלושת המצבים האלה דורשים פעולות שונות, ולקוח שיודע רק «שגיאה» אינו יכול להבחין ביניהם.
התיקון הוא ארכיטקטוני: תן לכל ריצה זהות אצווה עמידה, ותן למסדי הנתונים לענות על שאלות במקום לתת ללקוח לנחש.
מה מסד הנתונים באמת מבטיח
SQL Server ו-Oracle שניהם נותנים אטומיות בתוך טרנזקציה. אף אחד מהם לא נותן לך אטומיות בין שניהם. חיבור שאבד אינו משחית את מסד הנתונים ואינו כופה ביטול ידני, כי השרת פותר את הטרנזקציה שלו בלעדיך. מה שנשבר הוא הידע של הקורא על התוצאה.
Commit בנפרד פירושו commit בנפרד. VPN שנושא את שני החיבורים אינו ממזג שני commits ליחידת עבודה אחת.
ה-commit שלא שמעת עליו מעולם
מצב כשל אחד מעניש לוגיקת ניסיון חוזר נאיבית: השרת מבצע commit, והאישור לעולם אינו מגיע לקורא. Oracle מתעד זאת כבעיית התוצאה הלא ידועה ומספק לכך Transaction Guard במסגרת תיעוד הטרנזקציות. שגיאת תקשורת אינה ראיה ש-commit שנשלח נכשל, והתייחסות אליה כראיה היא הדרך שבה אצווה נשלחת פעמיים. ההבחנה חשובה ביותר בנתיב הניסיון החוזר, שבו למפעיל יש הודעת שגיאה ואין לו שום אות אחר לפעול לפיו.
לכן שלב ההתאוששות חייב לקרוא את התוצאה מהיעד במקום להסיק אותה מטקסט השגיאה.
תן להעברה זהות אצווה
כל ריצה מקבלת מזהה אצווה בלתי משתנה, והיעד רושם מה עשה עם המזהה הזה. מחזור החיים הוא ארבעה שלבים, והוא נראה זהה ללא תלות בספק:
- חלץ אצוות מקור מזוהה ובלתי משתנה עם סכימה וגבול מתועדים.
- העבר אותה לאזור ההכנה של היעד וזהה תוכן חסר או סותר לפני שמכריזים שהיא מוכנה.
- החל אותה לפי כללי הייחודיות או הנעילה של היעד עצמו ורשום את ההשלמה באותה טרנזקציה מקומית.
- התאם את התוצאה העמידה דרך הפרוטוקול הנתמך לפני אישור או ניסיון חוזר.
ניסיונות חוזרים משתמשים באותו מזהה. מזהה חדש לכל ניסיון מפרק את מניעת הכפילויות שהרגע בנית, מה שנשמע מובן מאליו עד שעוטף ניסיון חוזר מייצר אחד אוטומטית.
המזהה גם נותן לך משהו להתאים מולו מאוחר יותר, הרבה אחרי שתהליך הלקוח נעלם.
תפוס את האצווה, ואז החל
שלב ההחלה חייב לתפוס את מזהה האצווה, לבצע את שינויי העסק ולרשום את ההשלמה בטרנזקציה מקומית אחת. ביצוע הבדיקה וההוספה כהוראות נפרדות מחזיר את המירוץ שניסית להסיר. אם שני עובדים מתחרים, בדיוק תפיסה אחת מנצחת והשני מקבל הודעה על כך.
היעדר רשומת השלמה אינו ראיה שטרנזקציה בתהליך לעולם לא תבצע commit. התפיסה חייבת לסדר את הניסיונות המתחרים, או שהפרוטוקול חייב לקרוא את התוצאה העמידה לפני כל החלטה.
השתמש במנגנון הנתמך של מסד הנתונים לסידור הזה במקום בלולאת בדוק-וחזור בקוד היישום.
מה שהתכנון עדיין אינו יכול להבטיח
ההכנה הופכת את העבודה לניתנת להפעלה מחדש ומפחיתה את התלות בסשן ארוך אחד. היא אינה יוצרת commit אטומי יחיד על פני SQL Server, Oracle וכל תופעת לוואי חיצונית שהעבודה מבצעת. אם העסק באמת זקוק לכך, תכנן ותקף טרנזקציה מבוזרת נתמכת או תהליך התאמה, כולל מי הבעלים של עבודה שתוצאהּ אינו ודאי. כל דבר חלש מזה שייך ל-runbook התאמה, לא לקוד ההעברה.
קבל את ההפרעה בשלושה מקומות: במהלך ההעברה, במהלך ההחלה, ואחרי commit אך לפני האישור. לאחר מכן בדוק את התוצאה העסקית ולא את הודעת הלקוח, ותן ליומן האצוות לומר אם העבודה חלקית, מבוצעת commit או עדיין לא פתורה.