בדף הזה מוסבר איך להשתמש בסעיף FOR UPDATE בבידוד של קריאה חוזרת.
מנגנון הנעילה של סעיף FOR UPDATE שונה עבור קריאה חוזרת ובידוד ניתן לסדר. בניגוד לבידוד ברמת סריאליזציה, סעיף FOR UPDATE לא מקבל נעילות בבידוד של קריאה חוזרת. מידע נוסף על נעילות ב-FOR UPDATE זמין במאמר שימוש ב-SELECT FOR UPDATE בבידוד ניתן לסריאליזציה.
מידע נוסף על השימוש בסעיף FOR UPDATE זמין במדריכי העיון של GoogleSQL ושל PostgreSQL בנושא FOR UPDATE.
למה כדאי להשתמש בסעיף FOR UPDATE
כשעסקה מופעלת עם בידוד קריאה חוזרת, הנתונים שנשאלו על ידי ההצהרה SELECT תמיד מוחזרים בחותמת הזמן של תמונת המצב שנקבעה לעסקה. אם העסקה מבצעת עדכונים על סמך הנתונים שנשלחו בשאילתה, יכולות להיות בעיות בדיוק אם עסקה מקבילה גם מעדכנת את הנתונים שנשלחו בשאילתה. מידע נוסף זמין במאמר בנושא קונפליקטים של קריאה וכתיבה ונכונות.
כדי לוודא שהנתונים שנשלפים באמצעות ההצהרה SELECT עדיין תקפים כשהטרנזקציה מתבצעת, אפשר להשתמש בסעיף FOR UPDATE עם בידוד קריאה חוזרת. השימוש ב-FOR UPDATE מבטיח שהעסקאות יהיו תקינות למרות קונפליקטים של קריאה וכתיבה, שבהם יכול להיות שנתונים שונו על ידי עסקה אחרת בין הזמן שבו הם נקראו לבין הזמן שבו הם שונו.
תחביר של שאילתות
בקטע הזה מוסבר על תחביר השאילתות כשמשתמשים בסעיף FOR UPDATE.
השימוש הנפוץ ביותר הוא במשפט SELECT ברמה העליונה. לדוגמה:
SELECT SingerId, SingerInfo
FROM Singers WHERE SingerID = 5
FOR UPDATE;
הסעיף FOR UPDATE מבטיח שהנתונים שנשאלו על ידי ההצהרה SELECT
ו-SingerID = 5 עדיין תקפים כשהעסקה מתבצעת, וכך נמנעות בעיות של נכונות שיכולות לקרות אם עסקה מקבילה מעדכנת את הנתונים שנשאלו.
שימוש בהצהרות WITH
הסעיף FOR UPDATE לא מאמת את הטווחים שנסרקו בהצהרת WITH כשמציינים FOR UPDATE בשאילתה ברמה החיצונית של ההצהרה WITH.
בשאילתה הבאה, לא מתבצעת אימות של טווחים שנסרקו כי FOR UPDATE לא מועבר לשאילתת הביטויים הנפוצים של הטבלה (CTE).
WITH s AS (SELECT SingerId, SingerInfo FROM Singers WHERE SingerID > 5)
SELECT * FROM s
FOR UPDATE;
אם מציינים את סעיף FOR UPDATE בשאילתת ה-CTE, הטווח שנסרק בשאילתת ה-CTE מאומת.
בדוגמה הבאה, התאים SingerId ו-SingerInfo בשורות שבהן SingerId > 5 מאומתים.
WITH s AS
(SELECT SingerId, SingerInfo FROM Singers WHERE SingerId > 5 FOR UPDATE)
SELECT * FROM s;
שימוש בשאילתות משנה
אפשר להשתמש בסעיף FOR UPDATE בשאילתה ברמה החיצונית שיש לה שאילתה אחת או יותר. הטווחים שנסרקים על ידי השאילתה ברמה העליונה ובתוך שאילתות משנה עוברים אימות, למעט שאילתות משנה של ביטויים.
השאילתה הבאה מאמתת את התאים SingerId ו-SingerInfo בשורות שבהן SingerId > 5.
(SELECT SingerId, SingerInfo FROM Singers WHERE SingerId > 5) AS t
FOR UPDATE;
השאילתה הבאה לא מאמתת תאים בטבלה Albums כי היא נמצאת בשאילתת משנה של ביטוי. התאים SingerId ו-SingerInfo בשורות שמוחזרות על ידי שאילתת המשנה של הביטוי מאומתים.
SELECT SingerId, SingerInfo
FROM Singers
WHERE SingerId = (SELECT SingerId FROM Albums WHERE MarketingBudget > 100000)
FOR UPDATE;
שימוש בשאילתות לתצוגות
אפשר להשתמש בסעיף FOR UPDATE כדי לשלוח שאילתה לתצוגה, כמו בדוגמה הבאה:
CREATE VIEW SingerBio AS SELECT SingerId, FullName, SingerInfo FROM Singers;
SELECT * FROM SingerBio WHERE SingerId = 5 FOR UPDATE;
אי אפשר להשתמש בפסקה FOR UPDATE כשמגדירים תצוגה.
תרחישי שימוש שלא נתמכים
אין תמיכה בתרחישי השימוש הבאים של FOR UPDATE:
- כמנגנון הדדי למניעת הרצה של קוד מחוץ ל-Spanner: אל תשתמשו בנעילה ב-Spanner כדי להבטיח גישה בלעדית למשאב מחוץ ל-Spanner. יכול להיות ש-Spanner יבטל עסקאות. לדוגמה, אם מתבצע ניסיון חוזר לעסקה, באופן מפורש על ידי קוד האפליקציה או באופן מרומז על ידי קוד הלקוח, כמו מנהל ההתקנים של Spanner JDBC, מובטח שהנעילות יוחזקו רק במהלך הניסיון שאושר.
- בשילוב עם הרמז
LOCK_SCANNED_RANGES: אי אפשר להשתמש גם בסעיףFOR UPDATEוגם ברמזLOCK_SCANNED_RANGESבאותה שאילתה, אחרת Spanner מחזיר שגיאה. מידע נוסף מופיע במאמר השוואה לרמזLOCK_SCANNED_RANGES. - בשאילתות של חיפוש טקסט מלא: אי אפשר להשתמש בפסקה
FOR UPDATEבשאילתות שמשתמשות באינדקסים של חיפוש טקסט מלא. - בעסקאות לקריאה בלבד: סעיף
FOR UPDATEתקף רק בשאילתות שמופעלות בעסקאות לקריאה ולכתיבה. - בתוך הצהרות DDL: אי אפשר להשתמש בסעיף
FOR UPDATEבשאילתות בתוך הצהרות DDL, שמאוחסנות לביצוע מאוחר יותר. לדוגמה, אי אפשר להשתמש בסעיףFOR UPDATEכשמגדירים תצוגה.
המאמרים הבאים
- GoogleSQL
PostgreSQL
FOR UPDATE - איך משתמשים ב-SELECT FOR UPDATE בבידוד ניתן לסריאליזציה
- מידע נוסף על ההצעה
LOCK_SCANNED_RANGES - מידע על נעילה ב-Spanner