วิธีการย้อนกลับเมื่อเริ่ม 3 โพรซีเดอร์ที่เก็บไว้จากโพรซีเดอร์ที่เก็บไว้หนึ่งโพรซีเดอร์


23

ฉันมีโพรซีเดอร์ที่เก็บไว้ซึ่งประมวลผล 3 โพรซีเดอร์ที่เก็บไว้ภายในเท่านั้น ฉันใช้พารามิเตอร์ 1 ตัวเพื่อจัดเก็บเท่านั้นหากมาสเตอร์ SP ประสบความสำเร็จ

หากโพรซีเดอร์ที่เก็บครั้งแรกทำงานได้ดีในโพรซีเดอร์ที่เก็บข้อมูลหลัก แต่โพรซีเดอร์ที่เก็บข้อมูลที่สองล้มเหลวแล้วมันจะย้อนกลับ SP ทั้งหมดใน Master SP โดยอัตโนมัติหรือฉันต้องทำบางคำสั่งหรือไม่?

นี่คือขั้นตอนของฉัน:

CREATE PROCEDURE [dbo].[spSavesomename] 
    -- Add the parameters for the stored procedure here

    @successful bit = null output
AS
BEGIN
begin transaction createSavebillinginvoice
    begin Try
    -- SET NOCOUNT ON added to prevent extra result sets from
    -- interfering with SELECT statements.
    SET NOCOUNT ON;

   BEGIN 

   EXEC [dbo].[spNewBilling1]

   END

   BEGIN 

   EXEC [dbo].[spNewBilling2]

   END

   BEGIN 

   EXEC [dbo].[spNewBilling3]

   END 

   set @successful  = 1

   end Try

    begin Catch
        rollback transaction createSavesomename
        insert into dbo.tblErrorMessage(spName, errorMessage, systemDate) 
             values ('spSavesomename', ERROR_MESSAGE(), getdate())

        return
    end Catch
commit transaction createSavesomename
return
END

GO

ถ้าspNewBilling3โยนข้อผิดพลาด แต่คุณไม่ต้องการที่จะย้อนกลับspNewBilling2หรือspNewBilling1แล้วก็ลบออกจาก[begin|rollback|commit] transaction createSavebillinginvoice spSavesomename
Mike

คำตอบ:


56

ให้รหัสที่แสดงในคำถามเท่านั้นและสมมติว่าไม่มีโปรแกรมย่อยสามรายการใดที่มีการจัดการธุรกรรมอย่างชัดเจนดังนั้นใช่ข้อผิดพลาดในโปรแกรมย่อยสามรายการใด ๆ จะถูกดักจับและROLLBACKในCATCHบล็อกจะย้อนกลับทั้งหมด ของการทำงาน

แต่ต่อไปนี้เป็นสิ่งที่ควรทราบเกี่ยวกับธุรกรรม (อย่างน้อยใน SQL Server):

  • มีธุรกรรมจริงเพียงรายการเดียวเท่านั้น(ธุรกรรมแรก) ไม่ว่าคุณจะโทรกี่ครั้งก็ตามBEGIN TRAN

    • คุณสามารถตั้งชื่อการทำธุรกรรม (ตามที่คุณได้ทำที่นี่) และชื่อที่จะปรากฏในบันทึกการ แต่ตั้งชื่อเพียง แต่มีความหมายสำหรับครั้งแรก / ด้านนอกสุดของการทำธุรกรรม (เพราะอีกครั้งหนึ่งคือการทำธุรกรรม)
    • ทุกครั้งที่คุณโทรBEGIN TRANไม่ว่าจะมีชื่อหรือไม่เคาน์เตอร์ธุรกรรมจะเพิ่มขึ้น 1
    • คุณสามารถดูระดับปัจจุบันโดยการทำ SELECT @@TRANCOUNT;
    • COMMITคำสั่งใด ๆ ที่ออกเมื่อ@@TRANCOUNTอยู่ที่ 2 หรือสูงกว่าจะไม่ทำอะไรมากไปกว่าการลดทอนครั้งละหนึ่งรายการ
    • ไม่มีอะไรเกิดขึ้นจนกว่าจะมีการCOMMITออกเมื่อ@@TRANCOUNTอยู่ที่1
    • ในกรณีที่ข้อมูลข้างต้นไม่ได้ระบุอย่างชัดเจน: ไม่ว่าระดับธุรกรรมจะไม่มีการซ้อนธุรกรรมที่แท้จริง
  • บันทึกจุดที่อนุญาตให้มีการสร้างส่วนหนึ่งของการทำงานภายในรายการที่สามารถยกเลิกได้

    • บันทึกคะแนนถูกสร้าง / ทำเครื่องหมายผ่านSAVE TRAN {save_point_name}คำสั่ง
    • บันทึกคะแนนทำเครื่องหมายจุดเริ่มต้นของชุดย่อยของงานที่สามารถยกเลิกได้โดยไม่ต้องย้อนกลับไปทำธุรกรรมทั้งหมด
    • ชื่อจุดบันทึกไม่จำเป็นต้องไม่ซ้ำกัน แต่การใช้ชื่อเดียวกันมากกว่าหนึ่งครั้งยังคงสร้างจุดบันทึกที่แตกต่างกัน
    • บันทึกคะแนนสามารถซ้อนกัน
    • ไม่สามารถบันทึกคะแนนได้
    • ROLLBACK {save_point_name}บันทึกจุดที่สามารถยกเลิกได้ผ่านทาง (เพิ่มเติมในด้านล่างนี้)
    • การย้อนกลับจุดบันทึกจะยกเลิกการทำงานที่เกิดขึ้นหลังจากการโทรครั้งล่าสุดSAVE TRAN {save_point_name}รวมถึงจุดบันทึกที่สร้างขึ้นหลังจากที่มีการย้อนกลับถูกสร้างขึ้น (ดังนั้น "การซ้อน")
    • การย้อนกลับจุดบันทึกไม่มีผลต่อการนับธุรกรรม / ระดับ
    • งานใด ๆ ที่ทำก่อนที่จะเริ่มต้นSAVE TRANไม่สามารถยกเลิกได้ยกเว้นโดยการROLLBACKทำธุรกรรมเต็มรูปแบบทั้งหมด
    • เพียงเพื่อให้ชัดเจน: การออก a COMMITเมื่อ@@TRANCOUNTอยู่ที่ 2 หรือสูงกว่าจะไม่มีผลต่อคะแนนการบันทึก (เพราะอีกครั้งระดับการทำธุรกรรมที่สูงกว่า 1 ไม่มีอยู่นอกตัวนับนั้น)
  • คุณไม่สามารถกระทำธุรกรรมที่มีชื่อเฉพาะ ธุรกรรม "ชื่อ" หากระบุพร้อมกับCOMMITจะถูกละเว้นและมีอยู่เพื่อให้สามารถอ่านได้เท่านั้น

  • การROLLBACKออกโดยไม่มีชื่อจะย้อนกลับธุรกรรมทั้งหมด

  • ชื่อที่ROLLBACKออกจะต้องตรงกับ:

    • การทำธุรกรรมครั้งแรกสมมติว่าชื่อ:
      สมมติว่าไม่มีSAVE TRANการเรียกด้วยชื่อการทำธุรกรรมเดียวกันนี้จะย้อนกลับการทำธุรกรรมทั้งหมด
    • A "จุดบันทึก" (อธิบายไว้ข้างต้น):
      พฤติกรรมนี้จะ "เลิกทำ" การเปลี่ยนแปลงทั้งหมดที่เกิดขึ้นเนื่องจากมีการ SAVE TRAN {save_point_name}เรียกใช้ล่าสุด
    • หากการทำธุรกรรมครั้งแรกคือ a) ชื่อและ b) มีSAVE TRANคำสั่งที่ออกพร้อมกับชื่อแล้ว ROLLBACK แต่ละชื่อของธุรกรรมนั้นจะยกเลิกการบันทึกแต่ละจุดจนกว่าจะไม่มีชื่อเหลืออยู่ หลังจากนั้น ROLLBACK ที่ออกในชื่อนั้นจะย้อนกลับธุรกรรมทั้งหมด
    • ตัวอย่างเช่นสมมติว่าคำสั่งต่อไปนี้ถูกเรียกใช้ตามลำดับที่แสดง:

      BEGIN TRAN A -- @@TRANCOUNT is now 1
      -- DML Query 1
      SAVE TRAN A
      -- DML Query 2
      SAVE TRAN A
      -- DML Query 3
      
      BEGIN TRAN B -- @@TRANCOUNT is now 2
      SAVE TRAN B
      -- DML Query 4

      ตอนนี้ถ้าคุณออก (แต่ละสถานการณ์ต่อไปนี้เป็นอิสระจากกัน):

      • ROLLBACK TRAN Bหนึ่งครั้ง: จะยกเลิก "DML Query 4" @@TRANCOUNTยังคงเป็น 2
      • ROLLBACK TRAN Bสองครั้ง: จะเลิกทำ "DML Query 4" แล้วเกิดข้อผิดพลาดเนื่องจากไม่มีจุดบันทึกที่สอดคล้องกันสำหรับ "B" @@TRANCOUNTยังคงเป็น 2
      • ROLLBACK TRAN Aหนึ่งครั้ง: จะยกเลิก "DML Query 4" และ "DML Query 3" @@TRANCOUNTยังคงเป็น 2
      • ROLLBACK TRAN Aสองครั้ง: จะเลิกทำ "DML Query 4", "DML Query 3" และ "DML Query 2" @@TRANCOUNTยังคงเป็น 2
      • ROLLBACK TRAN Aสามครั้ง: จะยกเลิก "DML Query 4", "DML Query 3" และ "DML Query 2" จากนั้นจะย้อนกลับธุรกรรมทั้งหมด (ทั้งหมดที่เหลือคือ "DML Query 1") @@TRANCOUNTตอนนี้เป็น 0
      • COMMITหนึ่งครั้ง: @@TRANCOUNTลงไปที่ 1
      • COMMITหนึ่งครั้งแล้วROLLBACK TRAN Bครั้งหนึ่ง: @@TRANCOUNTลงไปที่ 1 จากนั้นจะยกเลิก "DML Query 4" (พิสูจน์ว่า COMMIT ไม่ได้ทำอะไรเลย) @@TRANCOUNTยังคงเป็น 1
  • ชื่อธุรกรรมและชื่อจุดบันทึก:

    • สามารถมีอักขระได้สูงสุด 32 ตัว
    • ได้รับการปฏิบัติเสมือนว่ามีการจัดเรียงไบนารี (ไม่คำนึงถึงตัวพิมพ์เล็กและตัวพิมพ์ใหญ่ตามเอกสารปัจจุบัน) โดยไม่คำนึงถึงการจัดเรียงระดับอินสแตนซ์หรือระดับฐานข้อมูล
    • สำหรับรายละเอียดโปรดดูที่ส่วนชื่อธุรกรรมของโพสต์ต่อไปนี้: มีอะไรในชื่อ: ภายใน Wacky World of T-SQL Identifiers
  • ขั้นตอนการจัดเก็บไม่ใช่ธุรกรรมโดยนัย แบบสอบถามแต่ละรายการหากไม่มีการเริ่มต้นธุรกรรมที่ชัดเจนเป็นธุรกรรมโดยนัย นี่คือเหตุผลที่การทำธุรกรรมที่ชัดเจนเกี่ยวกับแบบสอบถามเดียวไม่จำเป็นเว้นแต่จะมีเหตุผลเชิงโปรแกรมในการทำROLLBACKมิฉะนั้นข้อผิดพลาดใด ๆ ในแบบสอบถามคือการย้อนกลับอัตโนมัติของแบบสอบถามนั้น

  • เมื่อเรียกโพรซีเดอร์ที่เก็บไว้จะต้องออกโดยมีค่า@@TRANCOUNTเท่ากับเมื่อถูกเรียก หมายความว่าคุณไม่สามารถ:

    • เริ่มต้นBEGIN TRANใน proc โดยไม่ต้องทำมันโดยคาดว่าจะยอมรับในกระบวนการการเรียก / ผู้ปกครอง
    • คุณไม่สามารถออกคำสั่งROLLBACKหากธุรกรรมที่ชัดเจนเริ่มต้นขึ้นก่อนที่จะมีการเรียก proc เนื่องจากมันจะกลับมา@@TRANCOUNTเป็น 0

    หากคุณออกจากกระบวนงานที่เก็บไว้โดยมีจำนวนธุรกรรมที่สูงกว่าหรือต่ำกว่าเมื่อมันจ้องคุณจะได้รับข้อผิดพลาดคล้ายกับ:

    ข่าวสารเกี่ยวกับ 266, ระดับ 16, สถานะ 2, กระบวนงาน YourProcName, บรรทัด 0
    ธุรกรรมนับหลังจากดำเนินการระบุจำนวนไม่ตรงกันของคำสั่ง BEGIN และ COMMIT จำนวนก่อนหน้า = X, จำนวนปัจจุบัน = Y

  • ตัวแปรตารางเช่นเดียวกับตัวแปรปกติไม่ถูกผูกมัดโดยการทำธุรกรรม


เกี่ยวกับการจัดการธุรกรรมใน procs ที่สามารถเรียกได้ว่าเป็นอิสระ (และจำเป็นต้องมีการจัดการธุรกรรม) หรือการโทรจาก procs อื่น ๆ (จึงไม่ต้องการการจัดการธุรกรรม): สามารถทำได้ในสองวิธีที่แตกต่างกัน

วิธีที่ฉันจัดการกับมันมาหลายปีแล้วตอนนี้ที่ดูเหมือนว่าจะทำงานได้ดีก็คือBEGIN/ COMMIT/ ROLLBACKที่ชั้นนอกสุดเท่านั้น การเรียก sub-proc เพียงข้ามคำสั่งการทำธุรกรรม ฉันได้อธิบายไว้ด้านล่างสิ่งที่ฉันใส่ลงในแต่ละ proc (ดีแต่ละคนที่ต้องการจัดการธุรกรรม)

  • ที่ด้านบนของแต่ละ proc DECLARE @InNestedTransaction BIT;
  • ใช้งานง่ายBEGIN TRANทำ:

    IF (@@TRANCOUNT = 0)
    BEGIN
       SET @InNestedTransaction = 0;
       BEGIN TRAN; -- only start a transaction if not already in one
    END;
    ELSE
    BEGIN
       SET @InNestedTransaction = 1;
    END;
  • ใช้งานง่ายCOMMITทำ:

    IF (@@TRANCOUNT > 0 AND @InNestedTransaction = 0)
    BEGIN
       COMMIT;
    END;
  • ใช้งานง่ายROLLBACKทำ:

    IF (@@TRANCOUNT > 0 AND @InNestedTransaction = 0)
    BEGIN
       ROLLBACK;
    END;

วิธีการนี้ควรใช้วิธีเดียวกันโดยไม่คำนึงว่าธุรกรรมเริ่มต้นขึ้นภายใน SQL Server หรือเริ่มต้นที่ชั้นแอป

สำหรับเทมเพลตเต็มรูปแบบของการจัดการการทำธุรกรรมนี้ภายในTRY...CATCHโครงสร้างโปรดดูคำตอบของฉันสำหรับคำถาม DBA.SE ต่อไปนี้: เราจำเป็นต้องจัดการธุรกรรมในรหัส C # รวมถึงขั้นตอนการจัดเก็บหรือไม่


นอกเหนือจาก "พื้นฐาน" แล้วยังมีความแตกต่างของการทำธุรกรรมเพิ่มเติมที่ต้องระวัง:

  • ตามค่าเริ่มต้นธุรกรรมส่วนใหญ่จะไม่ย้อนกลับ / ยกเลิกโดยอัตโนมัติเมื่อเกิดข้อผิดพลาด ซึ่งมักจะไม่ใช่ปัญหาตราบใดที่คุณมีการจัดการข้อผิดพลาดที่เหมาะสมและเรียกROLLBACKตัวเอง อย่างไรก็ตามบางครั้งสิ่งต่าง ๆ มีความซับซ้อนเช่นในกรณีที่เกิดข้อผิดพลาดในการยกเลิกแบทช์หรือเมื่อใช้OPENQUERY(หรือเซิร์ฟเวอร์ที่เชื่อมโยงโดยทั่วไป) และเกิดข้อผิดพลาดในระบบระยะไกล ในขณะที่ข้อผิดพลาดส่วนใหญ่สามารถถูกดักจับได้โดยใช้TRY...CATCHมีสองข้อที่ไม่สามารถดักจับด้วยวิธีนั้นได้ (จำไม่ได้ว่ามีข้อผิดพลาดใดเกิดขึ้นในขณะนี้ - กำลังค้นคว้า) ในกรณีเหล่านี้คุณต้องใช้SET XACT_ABORT ONในการย้อนกลับธุรกรรมอย่างถูกต้อง

    ชุด XACT_ABORT ONทำให้ SQL Server ย้อนกลับธุรกรรมใด ๆทันที (หากมีการใช้งานอยู่) และยกเลิกชุดงานหากมีข้อผิดพลาดเกิดขึ้น การตั้งค่านี้มีอยู่ก่อน SQL Server 2005 ซึ่งแนะนำการTRY...CATCHสร้าง ส่วนใหญ่ที่TRY...CATCHจะจัดการกับสถานการณ์ส่วนใหญ่และอื่น ๆ ส่วนใหญ่ obsoletes XACT_ABORT ONความจำเป็นในการ แต่เมื่อใช้OPENQUERY(และอาจจะเป็นหนึ่งสถานการณ์อื่น ๆ ที่ผมจำไม่ได้ในขณะนี้) SET XACT_ABORT ON;แล้วคุณยังจะต้องใช้

  • ภายในของไกถูกตั้งค่าโดยปริยายXACT_ABORT ONนี้ทำให้เกิดการใด ๆ ที่ผิดพลาดภายในทริกเกอร์ที่จะยกเลิกคำสั่ง DML ทั้งที่ยิง Trigger

  • คุณควรจัดการข้อผิดพลาดที่เหมาะสมโดยเฉพาะอย่างยิ่งเมื่อใช้ธุรกรรม TRY...CATCHสร้างแนะนำใน SQL Server 2005 ให้ความหมายของการจัดการเกือบทุกสถานการณ์ต้อนรับการปรับปรุงมากกว่าการทดสอบ@@ERRORหลังจากแต่ละคำสั่งซึ่งไม่ได้ช่วยมากมีข้อผิดพลาดชุดยกเลิก

    TRY...CATCHแนะนำ "รัฐ" ใหม่อย่างไรก็ตาม เมื่อไม่ได้ใช้TRY...CATCHโครงสร้างหากคุณมีธุรกรรมที่ใช้งานอยู่และเกิดข้อผิดพลาดมีหลายเส้นทางที่สามารถทำได้:

    • XACT_ABORT OFFและข้อผิดพลาดการยกเลิกคำสั่ง: การทำธุรกรรมยังคงใช้งานอยู่และการประมวลผลดำเนินการต่อด้วยคำสั่งถัดไปถ้ามี
    • XACT_ABORT OFFและข้อผิดพลาดการยกเลิกแบทช์ส่วนใหญ่: ธุรกรรมยังคงใช้งานอยู่และการประมวลผลจะดำเนินต่อไปด้วยแบทช์ถัดไปหากมี
    • XACT_ABORT OFFและข้อผิดพลาดการยกเลิกแบทช์บางอย่าง: ธุรกรรมถูกย้อนกลับและการประมวลผลจะดำเนินการกับแบทช์ถัดไปถ้ามี
    • XACT_ABORT ONและข้อผิดพลาดใด ๆ : ธุรกรรมถูกย้อนกลับและการประมวลผลดำเนินการต่อด้วยชุดงานถัดไปหากมี


    HOWEVER เมื่อใช้TRY...CATCHงานข้อผิดพลาดในการยกเลิกชุดงานจะไม่ยกเลิกชุด แต่เป็นการโอนการควบคุมไปยังCATCHบล็อกแทน เมื่อXACT_ABORTเป็นOFFธุรกรรมจะยังคงใช้งานส่วนใหญ่ของเวลาและคุณจะต้องหรือส่วนใหญ่COMMIT ROLLBACKแต่เมื่อพบข้อผิดพลาดการยกเลิกแบทช์บางอย่าง (เช่นกับOPENQUERY) หรือเมื่อXACT_ABORTใดONธุรกรรมจะอยู่ในสถานะใหม่ "ไม่น่าเชื่อถือ" ในสถานะนี้คุณไม่สามารถและไม่COMMITสามารถทำการดำเนินการ DML ใด ๆ สิ่งที่คุณสามารถทำได้คือROLLBACKและSELECTคำสั่ง อย่างไรก็ตามในสถานะ "uncomittable" นี้ธุรกรรมถูกย้อนกลับเมื่อเกิดข้อผิดพลาดและการออกROLLBACKเป็นเพียงรูปแบบ แต่ต้องทำ

    ฟังก์ชั่นXACT_STATEสามารถนำมาใช้เพื่อตรวจสอบว่าการทำธุรกรรมมีการใช้งานผิดปกติหรือไม่มีอยู่ ก็จะแนะนำ (โดยบางส่วนอย่างน้อย) เพื่อตรวจสอบฟังก์ชั่นนี้ในCATCHบล็อกเพื่อตรวจสอบว่าผลที่ได้คือ-1(เช่น uncommitable) @@TRANCOUNT > 0แทนการทดสอบถ้า แต่ด้วยXACT_ABORT ONที่ควรจะเป็นรัฐที่เป็นไปได้เท่านั้นที่จะอยู่ในดังนั้นจึงดูเหมือนว่าการทดสอบ@@TRANCOUNT > 0และXACT_STATE() <> 0เทียบเท่า ในทางกลับกันเมื่อXACT_ABORTเป็นOFFและมีธุรกรรมที่ใช้งานอยู่แล้วมันเป็นไปได้ที่จะมีสถานะเป็นอย่างใดอย่างหนึ่ง1หรือ-1อยู่ในCATCHบล็อกซึ่งอนุญาตให้มีความเป็นไปได้ในการออกCOMMITแทนROLLBACK(แม้ว่าฉันจะไม่นึกถึงกรณี อยากจะCOMMITหากธุรกรรมสามารถกระทำได้) ข้อมูลเพิ่มเติมและการวิจัยเกี่ยวกับการใช้XACT_STATE()ภายในCATCHบล็อกด้วยXACT_ABORT ONสามารถพบได้ในคำตอบของฉันสำหรับคำถาม DBA.SE ต่อไปนี้: ในกรณีใดธุรกรรมสามารถกระทำจากภายในบล็อก CATCH เมื่อตั้ง XACT_ABORT เป็น ON . โปรดทราบว่ามีข้อผิดพลาดเล็กน้อยXACT_STATE()ที่ทำให้มันกลับมาผิดพลาด1ในบางสถานการณ์: XACT_STATE () ส่งคืน 1 เมื่อใช้ใน SELECT พร้อมกับตัวแปรระบบบางส่วน แต่ไม่มี FROM clause


หมายเหตุเกี่ยวกับรหัสเดิม:

  • คุณสามารถลบชื่อที่กำหนดให้กับการทำธุรกรรมเพราะมันไม่ได้ช่วยอะไรเลย
  • คุณไม่ต้องการBEGINและENDรอบการEXECโทรแต่ละครั้ง

2
มันเป็นคำตอบที่ดีดีจริงๆ
McNets

1
ว้าวนั่นคือคำตอบที่ครอบคลุม! ขอขอบคุณ! BTW dos หน้าต่อไปนี้แก้ไขข้อผิดพลาดที่คุณอ้างถึงซึ่งไม่ติดกับ Try ... Catch? (ภายใต้หัวข้อ "ข้อผิดพลาดได้รับผลกระทบโดยลอง ... จับ Construct"? technet.microsoft.com/en-us/library/ms175976(v=sql.110).aspx
jrdevdba

1
@jrdevdba ขอบคุณ :-) และยินดีต้อนรับคุณ เกี่ยวกับข้อผิดพลาดที่ไม่ได้ติดกับดักฉันหมายถึงสวยมากทั้งสอง: และCompile errors, such as syntax errors, that prevent a batch from running Errors that occur during statement-level recompilation, such as object name resolution errors that occur after compilation because of deferred name resolution.แต่สิ่งเหล่านี้จะไม่เกิดขึ้นบ่อยนักและเมื่อคุณพบสถานการณ์เช่นนั้นให้แก้ไข (หากเป็นข้อบกพร่องในรหัส) หรือวางไว้ในกระบวนการย่อย ( EXECหรือsp_executesql) เพื่อให้TRY...CATCHสามารถดักจับได้
โซโลมอน Rutzky

2

ใช่ถ้าเนื่องจากรหัสข้อผิดพลาดการย้อนกลับในคำสั่ง catch ของขั้นตอนการจัดเก็บหลักของคุณจะดำเนินการมันจะย้อนกลับการดำเนินการทั้งหมดที่ดำเนินการโดยคำสั่งโดยตรงหรือผ่านขั้นตอนการจัดเก็บที่ซ้อนอยู่

แม้ว่าคุณจะไม่ได้ใช้การทำธุรกรรมที่ชัดเจนใด ๆ ในขั้นตอนการจัดเก็บที่ซ้อนกันของคุณยังคงขั้นตอนการจัดเก็บเหล่านี้จะใช้การทำธุรกรรมโดยนัยและจะกระทำเมื่อเสร็จสิ้น ย้อนกลับการดำเนินการทั้งหมดโดยขั้นตอนการจัดเก็บซ้อนกันเหล่านี้หากขั้นตอนการจัดเก็บหลักล้มเหลวและการทำธุรกรรมมีการสำรองข้อมูลย้อนกลับ

ทุกครั้งที่มีการทำธุรกรรมใด ๆ หรือย้อนกลับตามการดำเนินการในตอนท้ายของธุรกรรมนอกสุด ถ้ามีการทำธุรกรรมด้านนอกธุรกรรมที่ซ้อนกันภายในจะถูกกำหนดเช่นกัน ถ้าธุรกรรมภายนอกถูกย้อนกลับธุรกรรมภายในทั้งหมดก็จะถูกย้อนกลับด้วย

สำหรับการอ้างอิงhttp://technet.microsoft.com/en-us/library/ms189336(v=sql.105).aspx

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.