none
rollback +@@Trancount RRS feed

  • שאלה

  • שלום רב

    1. TRIGGER ROLLBACK - אם בטריגר ביצעתי פעולה INSERT  + פעולות נוספות בשלב מסוים בטריגר בצעתי ROLLBACK , לא הגדרתי BEGIN TRAN. האם פעולת ה INSERT

    שבצעתי בתחילה נשמרה או שה ROLLBACK יחזור יבטל את כל הפעולות שבוצעו באותו טריגר?

    2. ֲֲאם אני מבצע בדיקה I

    0<If @@transcount   , אם אני מקבל תשובה חיובית אני מבצע COMMIT . האם זה יבצע COMMIT לכל הטרנזקציות הפתוחות?

    3. Timeout expire - נוצרה לי בעיה שלעיתים המערכת מבצעת ROLLBACK בעקבות TIMEOUT EXPIRE לאחר פעולה משמעותית . לדוגמא הודפסה חשבונית . אני מעונין לבצע COMMIT' , מייד לאחר הדפסת חשבונית. ברור לי שזה לא הפתרון לבעיה, אבל האם זה יכול להוות פתרון זמני מבלי לגרום לנזק אחר.

    תודה

    דודו

    יום רביעי 27 יוני 2012 15:27

תשובות

  • נניח שביצעת פעולת Insert לטבלה.
    פעולה זו היא טרנזקציה בודדת גם אם הכנסת מיליון שורות וגם אם לא הכרזת Begin Tran לפני ה-Insert.
    כעת נניח שלטבלה יש Trigger על Insert שמבצע שלל פעולות- מוסיף פה, מעדכן שם, וכו'.
    כל הפעולות של ה-Trigger נכללות בטרנזקציה הנ"ל (שוב- בלי שציינת Begin Tran): אם היא תצליח אזי גם ה-Insert יצליח וגם כל מה שב-Trigger,
    ואם תבצע/יתבצע RollBack- הכל לא יתבצע- לא ה-Insert ולא ה-Trigger.

    Blog: http://about.me/GeriReshef

    • סומן כתשובה על-ידי DavidNAgro יום רביעי 27 יוני 2012 20:04
    יום רביעי 27 יוני 2012 17:16

כל התגובות

  • נניח שביצעת פעולת Insert לטבלה.
    פעולה זו היא טרנזקציה בודדת גם אם הכנסת מיליון שורות וגם אם לא הכרזת Begin Tran לפני ה-Insert.
    כעת נניח שלטבלה יש Trigger על Insert שמבצע שלל פעולות- מוסיף פה, מעדכן שם, וכו'.
    כל הפעולות של ה-Trigger נכללות בטרנזקציה הנ"ל (שוב- בלי שציינת Begin Tran): אם היא תצליח אזי גם ה-Insert יצליח וגם כל מה שב-Trigger,
    ואם תבצע/יתבצע RollBack- הכל לא יתבצע- לא ה-Insert ולא ה-Trigger.

    Blog: http://about.me/GeriReshef

    • סומן כתשובה על-ידי DavidNAgro יום רביעי 27 יוני 2012 20:04
    יום רביעי 27 יוני 2012 17:16
  • גרי שלום

    תודה רבה.

    האם אתה יכול להתייחס גם לשאלות הללו.

    1. אם אני מבצע INSERT בטריגר ומייד COMMIT לאחר מכן ROLLBACK.

    א. האם במקרה שכזה פעולת ה INSERT  תתבצע?

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

    2. . Timeout expire - נוצרה לי בעיה שלעיתים המערכת מבצעת ROLLBACK בעקבות TIMEOUT EXPIRE לאחר פעולה משמעותית . לדוגמא הודפסה חשבונית . אני מעונין לבצע COMMIT' , מייד לאחר הדפסת חשבונית. ברור לי שזה לא הפתרון לבעיה, אבל האם זה יכול להוות פתרון זמני מבלי לגרום לנזק אחר.

    תודה רבה

    דודו

    יום רביעי 27 יוני 2012 20:04
  • לגבי נקודה 2 נשמע לי מעט מוזר ההסבר או האפיון שלך

    ההדפסה של החשבונית לא צריכה להיות חלק מטרנזקציה במקרה כזה. את ההדפסה אתה יכול לבצע בצורה א-סינכרונית עם שאר העבודה אם למשל תבצע אותה 1. באפליקציה חיצונית או 2. ב COMMAND SHELL דרך הטרנזקציה או 3. ב CLR דרך הטרנזקציה. במקרים אלו נפילת ההדפסה לא תשפיע על הטרנזקציה שיכולה להמשיך לעבוד וההדפסה יכולה להיות במקביל ולא לעקב (יש עוד שיטות כמובן לעבודה א-סינכרונית אבל אלו הדרכים הכי פשוטות אני חושב)

    דוגמה טובה ומאוד נפוצה היא למשל שליחת מייל שיכולה להיות ארוכה ולכן מבצעים אותה בצורה א-סינכרונית בדרך כלל.

    אם תשים לנו דוגמה של מה אתה מבצע נוכל אולי להבין יותר

    לגבי 1:

    אתה מחפש דרך לבצע את הפעולה חלקית או שואל רק לידע כללי? אם אתה רוצה לבצע חלק מהפעולה אתה יכול במקום לעשות שימוש ב ROLLBACK TRANSACTION לעשות שימוש ב SAVE TRANSACTION statement. כמו כן מותר להישתמש בטרנזקציה בתוך טרנזקציה לפעולה אם זה עוזר לך.

    אם זו שאלה של לימוד אז התשובות:

    אם מבצעים COMMIT אז ה batch הנוכחי מסתיים ואם תנסה אחרי זה להריץ rollback ואין טרנזקציה חיצונית תקבל הודעת שגיאה.

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

    למשל:

    CREATE TABLE TestTran (Cola int PRIMARY KEY, Colb char(3));
    GO
    
    CREATE TRIGGER TestTranTrigger
       ON TestTran
       AFTER INSERT
    AS 
    BEGIN
        SET NOCOUNT ON;
        COMMIT TRANSACTION
    END
    GO
    
    BEGIN TRANSACTION T1;
    GO
    
    INSERT INTO TestTran VALUES (2, 'bbb');
    GO
    -- כאן נקבל הודעת שגיאה שהטרנזקציה הסתיימה בתוך הטריגר
    -- אבל בנקודה זו הטרנזקציה הסתיימה בהצלחה
    -- ואתה יכול לבצע
    -- SELECT
    -- למשל מסשן אחר כדי לבדוק שהרשומה כבר נכנסה ואין נעילה של הטרנזקציה
    
    -- אם תריץ את החלק הבא תקבל שגיאה כי הטרנזקציה כבר סגורה
    rollback TRANSACTION T1;
    GO

    הערה: הרבה ממה שאתה שואל יותר מהר יהיה לך פשוט לנסות ולבדוק. אלו שאלות של כן/לא ולא שאלות של הדרכה :-)

    לכן התשובות הן: א. כן, ב. לא אלא רק על ה batch הנוכחי

    אני מקווה שזה נתן לך את התשובות


    signature

    יום רביעי 27 יוני 2012 20:59
    מנחה דיון