none
ביצוע sequence ידני בגירסאות שלפני 2012 ? RRS feed

  • שאלה

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

    update my_sq_tbl set @new_num=seq=seq+1

    הבעיה היא כיצד לדאוג, שהשורה הזו תתבצע עם commit מיידי, ותשחרר את טבלת ה seq, ולא תמתין עד סוף הטרנסקציה , ששורה זו עשוייה להיכלל בתוכה?

    יום ראשון 02 יוני 2013 20:57

תשובות

  • רונן, האפשרות של identity מתאימה למקרה הבודד, ולא למקרה שיש לך סדרה של , seq , כך שהיא לא מתאימה לצרכים שלי. הסיבה שביקשתי המלצה לקישור, היא כי ראיתי במספר מקומות שצריכים נעילות, ובחלק שלא צריכים נעילות. אכן הבנתי מתשובתו של גיא שאין צורך בנעילה. אני מתנצל

    1. זה אפיון חדש שלא היה לנו. חלק מרכזי מתשובה יעילה כפי שכתבתי מעל זה אפיון מלא :-)

    2. האם האפיון הזה משנה במשהו? האם זה אפיון מלא הפעם (כמובן שלא... פורום הוא לא מקום שאפשר ברגע להציג אפיון מלא) ולכן נמשיך עם תיאוריה וכללי אצבע:

    נכון (לא מדוייק... עוד רגע הסבר) IDENTITY כביכול נראה מתאים יותר למצב של SEQ בודד. אחרי הכל באותה טבלה לא מחזיקים כמה סדרות של IDENTITY עבור כמה מספרי SEQ שונים. אבל מי אמר לך להכניס הכל לטבלה אחת?!? זו מגבלה שאתה ייצרת לעצמך ואין לה שום משמעות (אפילו יש לה חסרונות) מבחינת המערכת. אתה מתכנן את המערכת ואתה קובע את הארכיטקטורה שלה. האם יש לך מגבלה באפיון למספר טבלאות? מישהו סופר לך כמה טבלאות יש לך ולפי זה יש תשלום :-) ? האם מספר טבלאות חשוב יותר ממיטוב? אם אחת מהתשובות היא כן אז הרי שזה משפיע על ההחלטה כמובן. האם המערכת שלך עובדת עם משתמש בודד או מאות אלפי כניסות בשנייה? נמשיך כאמור עם כללי אצבע...

    כיצד אתה חושב שעובד SEQ בגרסת 2012?!? הכל נכנס למקום אחד או שאנחנו מייצרים אלמנט שונה חדש עבור כל SEQ שרוצים?

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

    "אין צורך בנעילות"?!? גיא לא אמר את זה ואין אפשרות לבצע UPDATE ללא נעילות. אתה לא צריך לנהל את הנעילות כפי שגיא כתב מפני שאין UPDATE ללא נעילות החזקות ביותר (סוג X). הכוונה שהשרת כבר ינהל לך את הנעילות אבל הן שם.

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

    אני מבין שאין לזה פתרון ישיר, מכיוון ששורת ה update מבצעת לבסוף exlusive על השורה, וזה לא ירד עד סוף הטרסקציה.

    אני תוהה האם לא ניתן לבצע זאת דרך קריאה לקונטקסט אחר מתוך הטריגר, או שימוש ב service-broker עם המתנה לתשובה?

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

    למה אין פתרון ישיר?!? כתבתי לך פתרון ישיר בהודעה הראשונה שלי. עבודה עם פונקציה חיצונית כמו CLR מנתקת את הפעולה מהטרנזקציה בה היא נמצאת. ה CLR מורץ דרך השרת SQL אבל למעשה הוא תוכנה חיצונית לכל דבר. לכן גם בחישוב משאבים השרת לא מציג את החלק של ה CLR. הפתרון פשוט כאמור והוא קיים :-) זה לא אומר שהייתי בוחר בו בהכרח.

    אני לא רואה כרגע את הקשר לשירות ברוקר ולבעיה. שירות ברוקר יעיל למשל כאשר רוצים עבודה א-סינכרונית על ידי יצירת queue (תור) כלשהו. כאן בכל מקרה הנעילות יווצרו. שירות ברוקר יכול להעביר את הלחץ ממקום אחד לאחר, לעזור אולי בחיסכון של DEADLOCK כאשר הלחץ יועבר לתור (queue)  שהוא ינהל, אבל הוא לא ימטב מהירות פעילות. ההמתנה תמיד תהיה והעבודה הסינכרונית של אחד אחרי השני תמיד תהיה בעקבות נעילה X שתמיד תהיה ב UPDATE אחרת הדטא לא אמין. אולי תפרט מה הרעיון שיש לך בכיוון זה

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

    תוספת (חזרתי מטיול עם הכלב ויש לי זמן להוסיף סיכום קצר):

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

    כ"כלל אצבע" אני מעדיף לעבוד עם IDENTITY כברירת מחדל.


    signature

    • נערך על-ידי pituachMVP, Editor יום חמישי 06 יוני 2013 04:55
    • סומן כתשובה על-ידי Matanya Zac יום חמישי 06 יוני 2013 14:47
    יום חמישי 06 יוני 2013 03:59
    מנחה דיון
  • הי,

    במאמר שרונן הפנה אליו מתוךהאתר של  SQL Server CAT יש דוגמאות מצויינות למימוש Sequence. המאמר טוען שפתרון באמצעות IDENTITY הוא יותר יעיל. אני לא מסכים. מהניסיון שלי, הפתרון מבוסס ה-UPDATE יותר יעיל, בפרט בגירסאות שלפני SQL Server 2012, שם יש ל-IDENTITY הרבה Overhead.

    המאמר גם מציין פתרון לשאלה שלך לגבי עדכון ה-Sequence מחוץ ל-Scope של הטרנזקציה - Extended Stored Procedure. מסתבר שה-SSMA מממש Sequence בצורה כזאת בדיוק. כמו כן, כפי שרונן ציין, אפשר להשיג את אותה תוצאה באמצעות CLR.

    בהצלחה!

    -----------------------------
    גיא גלנצר
    יועץ ומדריך SQL Server
    Madeira - SQL Server Services
    http://www.madeira.co.il

    • סומן כתשובה על-ידי Matanya Zac יום חמישי 06 יוני 2013 14:47
    יום חמישי 06 יוני 2013 11:28
    מנחה דיון
  • תודה לרונן וגיא. מתנצל שלא ראיתי את פתרון ה CLR שהוצע בתשובה הראשונה, מומלץ להוריד את הבאנר מהתשובות, כך יותר קל להתמקד בתשובה. לצערינו לכולנו יש כללים תת הכרתיים לקריאת תשובה, ואין לראות בזה כפיות הטוב.

    בעניין של העדפת בפיתרון של identity על ידי החברים. אני מכבד כל העדפה. אני אישית רואה בזה דרך מאוד לא אלגנטית (מצטער על עירוב הרגש) מחוץ לטענה שמדובר בביצועים נמוכים יותר לפי הטענה שהושמעה כאן. כמו כן אינני רואה סיבה לחפש דרכים להעלים את הטבלאות האלו מה ssms , דבר שמפריע לעיני המפתח, גם אם אין לזה משמעות טכנית.

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



    • סומן כתשובה על-ידי Matanya Zac יום חמישי 06 יוני 2013 14:47
    • נערך על-ידי Matanya Zac יום חמישי 06 יוני 2013 15:00
    יום חמישי 06 יוני 2013 14:37

כל התגובות

  • למה צריך קישור? למה לא לתת את ההסבר כאן?

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

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

    את השימוש הפשוט של sequence ניתן לשחזר בצורה פשוטה על ידי טבלה עם טור אחד בלבד בסגנון

    CREATE TABLE [dbo].[SequenceTbl](
    	[SequenceFld] [int] IDENTITY(1,1) NOT NULL,
     CONSTRAINT [PK_SequenceTbl] PRIMARY KEY CLUSTERED 
    (
    	[SequenceFld] ASC
    )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
    ) ON [PRIMARY]

    עתה העבודה תהיה בדומה לעבודה עם sequence המובנה ב 2012. 

    * בטור מסוג IDENTITY בדיוק כמו ב sequence גדל הערך שלו גם אם מבוצע אחר כך roll back לטרנזקציה. למעשה הם עובדים דומה מאחורי הקלעים.

    ** אפשר לעבוד עם טריגרים כך שבכל הכנסה של נתון לטבלה מסויימת (נניח T2) אז יתבצעו בטריגר השלבים כך: (1) נכניס ערך חדש לטבלת ה Sequence ואז (2) נבחר את הערך האחרון של הסשן הנוכחי בטבלת ה Sequence ונכניס אותו לטור ה Sequence בטבלה שלנו. בערך משהו כזה:

    -- insert value to the Sequence table
    insert [SequenceTbl] DEFAULT VALUES 
    -- get the last IDENTITY we insert in order tpo insert the new table
    declare @LastID as int
    SELECT @LastID = SCOPE_IDENTITY()

    *** כאמור גם אם יהיה rollback הערך יגדל אם יוכנס לשם נתון אפילו אם הנתון ימחק ב ROLL BACK.

    **** אם הבעיה היא בלי קשר ל sequence ויותר דנה בכיצד לבצע הרצה של קוד הנמצא בתוך טרנזקציה מייד עם ההפעלה שלו בלי קשר ל COMMIT אז תמיד אפשר להפעיל פונקציה חיצונית (זו דרך לעקוף את ה ROLL BACK). למשל פונקציית CLR לא תבצע ROLL BACK אף פעם אם לא הוגדר כך במפורש.


    signature

    יום שני 03 יוני 2013 08:41
    מנחה דיון
  • הי,

    הפתרון שמבוסס על UPDATE יותר יעיל מהפתרון שמבוסס על INSERT ו-IDENTITY, מפני של-IDENTITY יש Overhead. צריך רק לקחת בחשבון שזה פתרון לא סטנדרטי (לא נתמך ב-ANSI-SQL).

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

    מקווה שעזרתי...

    -----------------------------
    גיא גלנצר
    יועץ ומדריך SQL Server
    Madeira - SQL Server Services
    http://www.madeira.co.il

    יום שלישי 04 יוני 2013 06:44
    מנחה דיון
  • תודה גיא. הרעיון נכון, להקדים את זה לפני הטרסקציה. אבל גם לצד התיאורתי, וגם לצד שאני עלול להתפתות להכניס את זה בתוך טריגר (אני יודע שזה רעיון גרוע בדרך כלל).

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

    או לחילופין שיש איזה הוראה שאומרת לו בפירוש, לבצע commit ללא קשר לטרנסקציה הקוראת.

    יום שלישי 04 יוני 2013 09:13
  • בהחלט נכון :-)

    * אם זה מתאים לצרכים הוצאת ה Sequence מחוץ לטרנזקציה זה רעיון טוב


    signature

    יום שלישי 04 יוני 2013 12:17
    מנחה דיון
  • בכל אופן לא ברור לי איזה סוג נעילה יש לבצע בזמן העדכון של טבלת ה seq ,

    נניח שזה ייכתב כך:

    declare @result as int
    update seq set @r=val=val+1 where id=1
    print @result
    שאלה ראשונה, האם השורה של ה update כולל הקריאה של הערך הנוכחי, היא אטומית? כנראה שלא. כלומר יש צורך בנעילה.

    זה צריך להיות נעילה על שורה (פשוט חבל לנעול את כל המספרים בטבלה), נניח 2 תהליכים כך:

    הליך 1                  הליך 2

    קריאה = 234

                             קריאה = 234

    כתיבה = 235 

                            כתיבה = 235         

     

            (UPDLOCK)       (HOLDLOCK)    (UPDLOCK, HOLDLOCK)    (TABLOCKX)
    ---------------------------------------------------------------------------
    SELECT    not blocked      not blocked       not blocked         blocked
    INSERT    not blocked        blocked           blocked           blocked
    UPDATE      blocked          blocked           blocked           blocked
    DELETE      blocked          blocked           blocked           blocked

    מכיוון שאני לא רוצה לנעול את כל הטבלה, אז אין אפשרות למנוע select , אזי ההליך השני נידון לכשלון!?

    אז מה הפתרון?

     

    • נערך על-ידי Matanya Zac יום רביעי 05 יוני 2013 16:11
    יום רביעי 05 יוני 2013 15:36
  • הי,

    אני עדיין לא מבין למה אתה מחפש דרך לבצע Commit רק לחלק מהטרנזקציה. למה לא לצרוך את ערכי ה-Sequence לפני/מחוץ לטרנזקציה? בכל מקרה, אני לא מכיר דרך כזאת ב-SQL Server.

    פקודת ה-UPDATE, כולל הקריאה של הערך הנוכחי היא כן פעולה אטומית. SQL Server קודם כל קורא את הערך הנוכחי, ובזמן הזה הוא משתמש ב-Update Lock, ואז הוא מעדכן את הערך, ובזמן הזה הוא ממיר את ה-Update Lock ב-Exclusive Lock. הוא לא משחרר את ה-Update Lock ואז לוקח נעילה חדשה, אלא מבצע המרה של הנעילה. זה מבטיח שבין הקריאה לכתיבה לא יכול להיכנס תהליך אחר שעושה את אותו הדבר. לכן אתה לא צריך להוסיף שום Lock Hint.

    -----------------------------
    גיא גלנצר
    יועץ ומדריך SQL Server
    Madeira - SQL Server Services
    http://www.madeira.co.il

    יום רביעי 05 יוני 2013 19:17
    מנחה דיון
  • אם היית עובד עם IDENTTY לא היית צריך לנהל נעילות ולא היית נתקל בנעילות מסוג X כמו ב UPDATE... כמו כן כל משתמש יכול לגשת לערך שהוא הכניס בלי בעיה בעזרת SCOPE_IDENTITY או בעזרת OUTPUT וכל הפעולות רצות במקביל. היית יכול לבצע גם BULK INSERT ועבודה במקביל. במקרה של UPDATE כל משתמש ממתין למשתמשים הקודמים. in-design אין עבודה במקביל אפילו תיאורטית! פשוט מפני שאין לך ערכים מקבילים אלא רק ערך בודד בטבלה.

    כאמור זו הצורה ש Sequence עובד מאחורי הקלעים לזכרוני (כמעט... הוא עובד עם CASH למעשה, יש גם ניקוי והדברים מנוהלים ברמת INSTANCE ולא ברמת טבלה ועוד.... אבל זה בדיוק הרעיון).

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

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

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

    *** מיטוב ברמת מסד הנתונים יכול להיות עבודה עם טבלה היושבת בזכרון (טבלה זמנית). הבעיה ש SQL עלול להעביר אותה לדיסק אם יחסר לו זכרון

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


    signature

    יום רביעי 05 יוני 2013 21:02
    מנחה דיון
  • לפעמים אנשים מרגישים יותר בטוחים כשהם מקבלים המלצה ממישהו שהם לא מכירים. זה עניין פסיכולוגי ידוע :-) בעיקר אם הממליץ הוא מהחברה הרשמית שמפתחת את המוצר... חיפשתי בשבילך קישור מעניין :-)

    אני ממליץ לעבור על הקישור הבא:

    Simulating Sequence Objects in SQL Server
    http://blogs.msdn.com/b/sqlcat/archive/2006/04/10/sql-server-sequence-number.aspx

    "Among the two options described above, Option 1 is widely used in different variations but prone to blocking/deadlocking.  Option 2 improves concurrency significantly with a simple approach."

    נחש מה האופציה השניה המוצגת שם או גש לראות

    אני מקווה שזה עוזר לך


    signature

    יום רביעי 05 יוני 2013 21:47
    מנחה דיון
  • רונן, האפשרות של identity מתאימה למקרה הבודד, ולא למקרה שיש לך סדרה של , seq , כך שהיא לא מתאימה לצרכים שלי. הסיבה שביקשתי המלצה לקישור, היא כי ראיתי במספר מקומות שצריכים נעילות, ובחלק שלא צריכים נעילות. אכן הבנתי מתשובתו של גיא שאין צורך בנעילה. אני מתנצל אם שאלתי לא הייתה ברורה דיה. ותודה על העזרה.

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

    אני מבין שאין לזה פתרון ישיר, מכיוון ששורת ה update מבצעת לבסוף exlusive על השורה, וזה לא ירד עד סוף הטרסקציה.

    אני תוהה האם לא ניתן לבצע זאת דרך קריאה לקונטקסט אחר מתוך הטריגר, או שימוש ב service-broker עם המתנה לתשובה?

    • נערך על-ידי Matanya Zac יום רביעי 05 יוני 2013 23:25
    יום רביעי 05 יוני 2013 22:32
  • רונן, האפשרות של identity מתאימה למקרה הבודד, ולא למקרה שיש לך סדרה של , seq , כך שהיא לא מתאימה לצרכים שלי. הסיבה שביקשתי המלצה לקישור, היא כי ראיתי במספר מקומות שצריכים נעילות, ובחלק שלא צריכים נעילות. אכן הבנתי מתשובתו של גיא שאין צורך בנעילה. אני מתנצל

    1. זה אפיון חדש שלא היה לנו. חלק מרכזי מתשובה יעילה כפי שכתבתי מעל זה אפיון מלא :-)

    2. האם האפיון הזה משנה במשהו? האם זה אפיון מלא הפעם (כמובן שלא... פורום הוא לא מקום שאפשר ברגע להציג אפיון מלא) ולכן נמשיך עם תיאוריה וכללי אצבע:

    נכון (לא מדוייק... עוד רגע הסבר) IDENTITY כביכול נראה מתאים יותר למצב של SEQ בודד. אחרי הכל באותה טבלה לא מחזיקים כמה סדרות של IDENTITY עבור כמה מספרי SEQ שונים. אבל מי אמר לך להכניס הכל לטבלה אחת?!? זו מגבלה שאתה ייצרת לעצמך ואין לה שום משמעות (אפילו יש לה חסרונות) מבחינת המערכת. אתה מתכנן את המערכת ואתה קובע את הארכיטקטורה שלה. האם יש לך מגבלה באפיון למספר טבלאות? מישהו סופר לך כמה טבלאות יש לך ולפי זה יש תשלום :-) ? האם מספר טבלאות חשוב יותר ממיטוב? אם אחת מהתשובות היא כן אז הרי שזה משפיע על ההחלטה כמובן. האם המערכת שלך עובדת עם משתמש בודד או מאות אלפי כניסות בשנייה? נמשיך כאמור עם כללי אצבע...

    כיצד אתה חושב שעובד SEQ בגרסת 2012?!? הכל נכנס למקום אחד או שאנחנו מייצרים אלמנט שונה חדש עבור כל SEQ שרוצים?

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

    "אין צורך בנעילות"?!? גיא לא אמר את זה ואין אפשרות לבצע UPDATE ללא נעילות. אתה לא צריך לנהל את הנעילות כפי שגיא כתב מפני שאין UPDATE ללא נעילות החזקות ביותר (סוג X). הכוונה שהשרת כבר ינהל לך את הנעילות אבל הן שם.

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

    אני מבין שאין לזה פתרון ישיר, מכיוון ששורת ה update מבצעת לבסוף exlusive על השורה, וזה לא ירד עד סוף הטרסקציה.

    אני תוהה האם לא ניתן לבצע זאת דרך קריאה לקונטקסט אחר מתוך הטריגר, או שימוש ב service-broker עם המתנה לתשובה?

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

    למה אין פתרון ישיר?!? כתבתי לך פתרון ישיר בהודעה הראשונה שלי. עבודה עם פונקציה חיצונית כמו CLR מנתקת את הפעולה מהטרנזקציה בה היא נמצאת. ה CLR מורץ דרך השרת SQL אבל למעשה הוא תוכנה חיצונית לכל דבר. לכן גם בחישוב משאבים השרת לא מציג את החלק של ה CLR. הפתרון פשוט כאמור והוא קיים :-) זה לא אומר שהייתי בוחר בו בהכרח.

    אני לא רואה כרגע את הקשר לשירות ברוקר ולבעיה. שירות ברוקר יעיל למשל כאשר רוצים עבודה א-סינכרונית על ידי יצירת queue (תור) כלשהו. כאן בכל מקרה הנעילות יווצרו. שירות ברוקר יכול להעביר את הלחץ ממקום אחד לאחר, לעזור אולי בחיסכון של DEADLOCK כאשר הלחץ יועבר לתור (queue)  שהוא ינהל, אבל הוא לא ימטב מהירות פעילות. ההמתנה תמיד תהיה והעבודה הסינכרונית של אחד אחרי השני תמיד תהיה בעקבות נעילה X שתמיד תהיה ב UPDATE אחרת הדטא לא אמין. אולי תפרט מה הרעיון שיש לך בכיוון זה

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

    תוספת (חזרתי מטיול עם הכלב ויש לי זמן להוסיף סיכום קצר):

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

    כ"כלל אצבע" אני מעדיף לעבוד עם IDENTITY כברירת מחדל.


    signature

    • נערך על-ידי pituachMVP, Editor יום חמישי 06 יוני 2013 04:55
    • סומן כתשובה על-ידי Matanya Zac יום חמישי 06 יוני 2013 14:47
    יום חמישי 06 יוני 2013 03:59
    מנחה דיון
  • זק מצאתי שרשור שפתחת בשנת 2011 ולא סגרת אותו :-)

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

    * בכל סיום בעיה יש לעבור על כל השירשור ולסמן את כל התשובות שקיבלת + לסמן כל הודעה מועילה בצורה זו או אחרת => זה כמובן עוזר למי שמחפש תשובות ורואה שהשאלה קיבלה תשובה (כמגיע ממנוע חיפוש למשל) ולא פחות מכך זה גם מוסיף נקודות למי שניסה לעזור או לקח חלק בדיון

    http://social.msdn.microsoft.com/Forums/he-IL/sqlhe/thread/6b2a8101-9a93-440a-b7ce-03c90576001d


    signature

    יום חמישי 06 יוני 2013 09:51
    מנחה דיון
  • הי,

    במאמר שרונן הפנה אליו מתוךהאתר של  SQL Server CAT יש דוגמאות מצויינות למימוש Sequence. המאמר טוען שפתרון באמצעות IDENTITY הוא יותר יעיל. אני לא מסכים. מהניסיון שלי, הפתרון מבוסס ה-UPDATE יותר יעיל, בפרט בגירסאות שלפני SQL Server 2012, שם יש ל-IDENTITY הרבה Overhead.

    המאמר גם מציין פתרון לשאלה שלך לגבי עדכון ה-Sequence מחוץ ל-Scope של הטרנזקציה - Extended Stored Procedure. מסתבר שה-SSMA מממש Sequence בצורה כזאת בדיוק. כמו כן, כפי שרונן ציין, אפשר להשיג את אותה תוצאה באמצעות CLR.

    בהצלחה!

    -----------------------------
    גיא גלנצר
    יועץ ומדריך SQL Server
    Madeira - SQL Server Services
    http://www.madeira.co.il

    • סומן כתשובה על-ידי Matanya Zac יום חמישי 06 יוני 2013 14:47
    יום חמישי 06 יוני 2013 11:28
    מנחה דיון
  • תודה לרונן וגיא. מתנצל שלא ראיתי את פתרון ה CLR שהוצע בתשובה הראשונה, מומלץ להוריד את הבאנר מהתשובות, כך יותר קל להתמקד בתשובה. לצערינו לכולנו יש כללים תת הכרתיים לקריאת תשובה, ואין לראות בזה כפיות הטוב.

    בעניין של העדפת בפיתרון של identity על ידי החברים. אני מכבד כל העדפה. אני אישית רואה בזה דרך מאוד לא אלגנטית (מצטער על עירוב הרגש) מחוץ לטענה שמדובר בביצועים נמוכים יותר לפי הטענה שהושמעה כאן. כמו כן אינני רואה סיבה לחפש דרכים להעלים את הטבלאות האלו מה ssms , דבר שמפריע לעיני המפתח, גם אם אין לזה משמעות טכנית.

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



    • סומן כתשובה על-ידי Matanya Zac יום חמישי 06 יוני 2013 14:47
    • נערך על-ידי Matanya Zac יום חמישי 06 יוני 2013 15:00
    יום חמישי 06 יוני 2013 14:37
  • תודה רבה על הפרגון!

    כיף לשמוע!

    -----------------------------
    גיא גלנצר
    יועץ ומדריך SQL Server
    Madeira - SQL Server Services
    http://www.madeira.co.il
    יום ראשון 09 יוני 2013 13:03
    מנחה דיון