Tôi đã phát triển T-SQL được vài năm và luôn đào sâu hơn nữa, tiếp tục tìm hiểu tất cả những gì tôi có thể về tất cả các khía cạnh của ngôn ngữ. Gần đây tôi đã bắt đầu làm việc tại một công ty mới và đã nhận được những gì tôi nghĩ là một gợi ý kỳ lạ liên quan đến các giao dịch. Đừng bao giờ sử dụng chúng. Thay vào đó, sử dụng một cách giải quyết mô phỏng một giao dịch. Điều này đến từ DBA của chúng tôi, người làm việc trong một cơ sở dữ liệu với rất nhiều giao dịch và sau đó, rất nhiều chặn. Cơ sở dữ liệu tôi chủ yếu làm việc không gặp phải vấn đề này và tôi thấy các giao dịch đã được sử dụng trong quá khứ.
Tôi hiểu rằng việc chặn được mong đợi với các giao dịch vì bản chất của chúng là làm như vậy và nếu bạn có thể thoát khỏi mà không cần sử dụng, thì bằng mọi cách hãy làm điều đó. Nhưng tôi có nhiều dịp mà mỗi câu lệnh PHẢI thực thi thành công. Nếu một thất bại tất cả họ phải thất bại để cam kết.
Tôi luôn giữ phạm vi giao dịch của mình càng hẹp càng tốt, luôn được sử dụng cùng với SET XACT_ABORT ON và luôn trong TRY / CATCH.
Thí dụ:
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
Đây là những gì họ đề nghị mà tôi làm.
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
Câu hỏi của tôi cho cộng đồng như sau. Điều này có ý nghĩa như một cách giải quyết khả thi cho các giao dịch?
Ý kiến của tôi từ những gì tôi biết về giao dịch và giải pháp đang đề xuất là không, đây không phải là giải pháp khả thi và đưa ra nhiều điểm thất bại.
Trong cách giải quyết được đề xuất, tôi thấy bốn giao dịch ngầm xảy ra. Hai lần chèn trong thử và sau đó thêm hai giao dịch cho các lần xóa trong lần bắt. Nó thực hiện các thao tác chèn nhưng không quay trở lại nên không có gì thực sự quay trở lại.
Đây là một ví dụ rất cơ bản để chứng minh khái niệm mà họ đang đề xuất. Một số quy trình được lưu trữ thực tế mà tôi đã thực hiện để làm cho chúng hoàn toàn dài và khó quản lý bởi vì việc cuộn lại nhiều tập kết quả với hai giá trị tham số trong ví dụ này trở nên khá phức tạp như bạn có thể tưởng tượng. Vì "quay trở lại" hiện đang được thực hiện thủ công, cơ hội để bỏ lỡ điều gì đó thực sự.
Một vấn đề khác mà tôi nghĩ tồn tại là thời gian chờ hoặc kết nối bị đứt. Điều này vẫn còn được khôi phục? Đây là hiểu biết của tôi về lý do tại sao nên sử dụng SET XACT_ABORT ON để trong những trường hợp này, giao dịch sẽ quay trở lại.
Cảm ơn phản hồi của bạn trước!