הבלוג של גרי רשף

06/10/2010

טרנזקציות – מה לא ידעתי עד כה?

Filed under: Uncategorized — תגיות: , , , , , , — גרי רשף @ 14:19

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

למשל הקוד הבא- פותחים טרנזקציה ראשית, מעדכנים טבלה, פותחים טרנזקציה משנית, מעדכנים טבלה, מבצעים Commit לטרנזקציה המשנית, ו-RollBack לראשית:

Use tempdb;

Go

IF Object_Id('T_Trn','U') Is Not Null Drop Table T_Trn;

Go

Create Table T_Trn(I Int);

Go

Begin Tran Tr1;

Go

Insert Into T_Trn Values(1);

Go

Begin Tran Tr2;

Go

Insert Into T_Trn Values(2);

Go

Commit Tran Tr2;

Go

Rollback;

Go

Select * From T_Trn;

Go

האם ה-Commit הראשון שומר "באופן בלתי הפיך" את הערך 2 או שמא זה לא נגמר עד שהגברת מתחילה לשיר ומתבצע ה-Commit הסופי על הכל?

1. אם בסוף מתבצע Rollback- מתבטל כל מה שנעשה במהלך הטרנזקציה – כולל מה שנעשה לו Commit בטרנזקציה פנימית (למעט Save Point כפי שיוסבר בהמשך).

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

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

סעיף 1 די הגיוני בדיעבד: הרי כל פקודת DML היא טרנזקציה גם אם לא התבצע Begin Tran לפניה ו-Commit אחריה, ואם היא התבצעה במהלך טרנזקציה כללית – ביצוע Rollback יבטל אותה.

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

While @@TranCount>0 Commit;

לא שזו התנהלות נכונה מבחינה מערכתית, אבל מי אני שאחסום שור בדישו?

ניתן לבצע Commit חלקי בעזרת Save Tran:

Begin Tran MyTrn;

Insert Into T_Trn Select 3;

Save Tran MyTrn;

Insert Into T_Trn Select 4;

Rollback Tran MyTrn;

Select * From T_Trn;

Go

הערך 3 נשמר בטבלה חרף פקודת ה-Rollback מכיוון שהתבצע Save Tran אחרי הכנסתו. יחד עם זאת- אם התבצע Save Tran לטרנזקציה משנית, Rollback יבטל אותו!

כאשר עובדים על שרת נוסף דרך Linked Server ניתן להשתמש לצורך כך ב-Distributed Transactions: השימוש דומה לטרנזקציות רגילות, ורק יש לפתוח אותה בפקודת Begin Distributed Tran MyTran; (Commit ו-Rollback מתבצעים ללא שינוי).

לגבי שימוש באופציית Xact_Abort ובפונקציה Xact_State – ניתן לעיין בפוסט קודם.

מודעות פרסומת

להגיב »

עדיין אין תגובות.

RSS feed for comments on this post. TrackBack URI

כתיבת תגובה

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

הלוגו של WordPress.com

אתה מגיב באמצעות חשבון WordPress.com שלך. לצאת מהמערכת / לשנות )

תמונת Twitter

אתה מגיב באמצעות חשבון Twitter שלך. לצאת מהמערכת / לשנות )

תמונת Facebook

אתה מגיב באמצעות חשבון Facebook שלך. לצאת מהמערכת / לשנות )

תמונת גוגל פלוס

אתה מגיב באמצעות חשבון Google+ שלך. לצאת מהמערכת / לשנות )

מתחבר ל-%s

יצירה של אתר חינמי או בלוג ב־WordPress.com.

%d בלוגרים אהבו את זה: