ฉันได้พัฒนา T-SQL มาหลายปีแล้วและกำลังขุดอยู่เสมอและเรียนรู้ทุกอย่างที่เกี่ยวกับภาษาได้อย่างต่อเนื่อง ฉันเพิ่งเริ่มทำงานกับ บริษัท ใหม่และได้รับสิ่งที่ฉันคิดว่าเป็นข้อเสนอแนะแปลก ๆ เกี่ยวกับการทำธุรกรรม ไม่เคยใช้พวกเขา ใช้วิธีแก้ปัญหาที่จำลองธุรกรรมแทน นี่มาจาก DBA ของเราที่ทำงานในฐานข้อมูลเดียวกับธุรกรรมจำนวนมากและต่อมามีการบล็อกจำนวนมาก ฐานข้อมูลที่ฉันทำงานเป็นหลักไม่ประสบปัญหานี้และฉันเห็นว่ามีการใช้ธุรกรรมในอดีต
ฉันเข้าใจว่าการปิดกั้นเป็นสิ่งที่คาดว่าจะเกิดขึ้นเนื่องจากเป็นไปตามปกติของพวกเขาและถ้าคุณสามารถหลีกเลี่ยงได้โดยไม่ต้องใช้สิ่งใดสิ่งหนึ่ง แต่ฉันมีหลายครั้งที่แต่ละคำสั่งต้องทำงานสำเร็จ หากล้มเหลวพวกเขาทั้งหมดจะต้องล้มเหลวในการกระทำ
ฉันรักษาขอบเขตการทำธุรกรรมของฉันให้แคบที่สุดเสมอใช้ร่วมกับ SET XACT_ABORT ON เสมอและอยู่ในการทดลอง / จับ
ตัวอย่าง:
CREATE SCHEMA someschema;
GO
CREATE TABLE someschema.tableA
(id INT NOT NULL IDENTITY(1, 1) PRIMARY KEY,
ColA VARCHAR(10) NOT NULL
);
GO
CREATE TABLE someschema.tableB
(id INT NOT NULL IDENTITY(1, 1) PRIMARY KEY,
ColB VARCHAR(10) NOT NULL
);
GO
CREATE PROCEDURE someschema.ProcedureName @ColA VARCHAR(10),
@ColB VARCHAR(10)
AS
SET NOCOUNT, XACT_ABORT ON;
BEGIN
BEGIN TRY
BEGIN TRANSACTION;
INSERT INTO someschema.tableA(ColA)
VALUES(@ColA);
INSERT INTO someschema.tableB(ColB)
VALUES(@ColB);
--Implement error
SELECT 1/0
COMMIT TRANSACTION;
END TRY
BEGIN CATCH
IF @@trancount > 0
BEGIN
ROLLBACK TRANSACTION;
END;
THROW;
RETURN;
END CATCH;
END;
GO
นี่คือสิ่งที่พวกเขาแนะนำว่าฉันทำ
GO
CREATE PROCEDURE someschema.ProcedureNameNoTransaction @ColA VARCHAR(10),
@ColB VARCHAR(10)
AS
SET NOCOUNT ON;
BEGIN
BEGIN TRY
DECLARE @tableAid INT;
DECLARE @tableBid INT;
INSERT INTO someschema.tableA(ColA)
VALUES(@ColA);
SET @tableAid = SCOPE_IDENTITY();
INSERT INTO someschema.tableB(ColB)
VALUES(@ColB);
SET @tableBid = SCOPE_IDENTITY();
--Implement error
SELECT 1/0
END TRY
BEGIN CATCH
DELETE FROM someschema.tableA
WHERE id = @tableAid;
DELETE FROM someschema.tableB
WHERE id = @tableBid;
THROW;
RETURN;
END CATCH;
END;
GO
คำถามของฉันที่มีต่อชุมชนมีดังนี้ สิ่งนี้สมเหตุสมผลหรือไม่ที่เป็นวิธีแก้ปัญหาสำหรับการทำธุรกรรม?
ความคิดเห็นของฉันจากสิ่งที่ฉันรู้เกี่ยวกับธุรกรรมและสิ่งที่วิธีแก้ปัญหาเสนอคือไม่นี่ไม่ใช่วิธีแก้ปัญหาที่ใช้การได้และแนะนำจุดล้มเหลวมากมาย
ในวิธีแก้ปัญหาที่แนะนำฉันเห็นสี่ธุรกรรมโดยนัยที่เกิดขึ้น ทั้งสองแทรกในการลองแล้วอีกสองธุรกรรมสำหรับการลบในการจับ มันจะ "เลิกทำ" เม็ดมีด แต่ไม่มีการย้อนกลับอะไรเลยดังนั้นจึงไม่มีสิ่งใดถูกย้อนกลับได้
นี่เป็นตัวอย่างพื้นฐานที่แสดงให้เห็นถึงแนวคิดที่พวกเขากำลังแนะนำ ขั้นตอนการจัดเก็บจริงบางอย่างที่ฉันทำนี้ทำให้พวกเขาใช้เวลานานและยากที่จะจัดการเพราะ "ย้อนกลับ" ชุดผลลัพธ์หลายรายการกับค่าพารามิเตอร์สองค่าในตัวอย่างนี้ค่อนข้างซับซ้อนอย่างที่คุณจินตนาการ เนื่องจาก "ย้อนกลับ" กำลังทำด้วยตนเองตอนนี้โอกาสที่จะพลาดบางสิ่งเพราะจริง
ปัญหาอื่นที่ฉันคิดว่ามีอยู่สำหรับการหมดเวลาหรือการเชื่อมต่อที่ตัดขาด สิ่งนี้ยังคงย้อนกลับได้ไหม? นี่คือความเข้าใจของฉันว่าทำไมควรใช้ SET XACT_ABORT ON เพื่อให้ในกรณีเหล่านี้ธุรกรรมจะย้อนกลับ
ขอบคุณสำหรับความคิดเห็นของคุณล่วงหน้า!