나는 몇 년 동안 T-SQL을 개발해 왔으며 항상 더 깊이 파고 들어 언어의 모든 측면에 대해 가능한 모든 것을 계속 배우고 있습니다. 나는 최근에 새로운 회사에서 일하기 시작했고 거래에 관한 이상한 제안을 받았다. 절대 사용하지 마십시오. 대신 트랜잭션을 시뮬레이트하는 임시 해결책을 사용하십시오. 이것은 많은 트랜잭션과 많은 블로킹으로 하나의 데이터베이스에서 작업하는 DBA에서 온 것입니다. 내가 주로 일하는 데이터베이스는이 문제로 고통받지 않으며 과거에 트랜잭션이 사용 된 것으로 보입니다.
나는 본질적으로 거래가 차단되기 때문에 차단이 예상된다는 것을 알고 있으며, 하나를 사용하지 않고 도망 갈 수 있다면 반드시 그렇게하십시오. 그러나 각 문장이 성공적으로 실행되어야하는 경우가 많이 있습니다. 하나가 실패하면 모두 커밋하지 않아야합니다.
나는 항상 거래 범위를 가능한 한 좁게 유지했으며 항상 SET XACT_ABORT ON과 함께 사용되며 항상 TRY / CATCH 내에서 사용되었습니다.
예:
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을 사용해야하는 이유에 대한 이해입니다. 이러한 경우 트랜잭션이 롤백됩니다.
미리 의견을 보내 주셔서 감사합니다.