저장 거래 vs 트랜잭션을 시작(SQL Server)어떻게 둥지를 거래질
-
14-12-2019 - |
문제
는 저장 프로시저를 사용하고 있는 요구를 설정 포인트를 저장할 수 있도록 특정 상황에서,모든 사항을 취소했고 오류를 반환하는 코드를 호출자 또는 받아들이는지를 확고 성공을 반환하여 발신번호를 입력하실 수 있습니다.그러나 나는 그것을 필요로 작동하는지 여부를 호출자는 이미 트랜잭션을 시작하거나지 않습니다.문서가 매우 혼란에서이다.여기에 내가 무엇을 생각하는 것입니다 작업을,하지만 나는 특정의 모든 효과.
일-이 Stored Procedure (SP)
이라고 합니다.그래서 내가 알지 못하는 경우 그들은 트랜잭션을 시작 또는지...는 경우에는 사용자가 필요 시작하는 트랜잭션을 사용하여 내 SP,나는 아직도에 대한 질문에 적절한 사용 Save Points
...
내 SP 을 테스트하는 경우는 트랜잭션이 진행되고,그렇지 않은 경우,시작하나 BEGIN TRANSACTION
.트랜잭션은 이미 진행 중에는 것입니다 대신 생성을 저장점 SAVE TRANSACTION MySavePointName
, 고 사실 이것은 무엇을 했습니다.
그런 다음 필요한 경우에는 롤백을 경우,변경했다 BEGIN TRANSACTION
이전 다음 ROLLBACK TRANSACTION
.가 저장 점,다음 ROLLBACK TRANSACTION MySavePointName
.이 시나리오 작동하는 것 같다.
여기에 내가 작동하려는 경우를 유지하는 작업을 했는 경우,시작하는 트랜잭션을 실 COMMIT TRANSACTION
.하지만 만약 내가 만들었을까요?나 COMMIT TRANSACTION MySavePointName
, 지만,다음 호출을 시도 commit 해당 트랜잭션 오류:
커미 TRANSACTION 요청이 있는 해당 트랜잭션을 시작.
그래서 궁금하네요 그런 다음-저장 점 롤백할 수 있습니다(작품: ROLLBACK TRANSACTION MySavePointName
롤하지 않습니다 다시 발신자의 거래).하지만 아마도 하나 결코 필요하"commit"그것이 무엇입니까?그것은 단지 숙박이 있는 경우에,당신이 필요로 롤백하지만,간다면 원래밋(또는 압연 후)?
이 있는 경우"더 나은"방법"nest"트랜잭션을 주시기 바랍 빛을 발산뿐만 아니라.나는 생각하지 않은 방법으로 둥지 BEGIN TRANSACTION
하지만 롤백 또는 헌 내부 transaction.보 ROLLBACK
은 항상 목록시 최고 거래하는 동안, COMMIT
단순히 감소 @@trancount
.
해결책
내가 믿고 나는 생각이 모두 밖으로 지금,그래서 난 것이 답이 나 자신의 질문을...
나는 심지어 블로그를 내 결과 더 많은 정보를 원하는 경우에는 http://geekswithblogs.net/bbiales/archive/2012/03/15/how-to-nest-transactions-nicely---quotbegin-transactionquot-vs-quotsave.aspx
그래서 내 SP 시작으로 이런 시작하고,새로운 트랜잭션이 존재하지 않는 경우에는 사용 하지만인 경우 이미 진행 중인:
DECLARE @startingTranCount int
SET @startingTranCount = @@TRANCOUNT
IF @startingTranCount > 0
SAVE TRANSACTION mySavePointName
ELSE
BEGIN TRANSACTION
-- …
그런 다음,준비가 되면 변경 내용을 적용,당신은 단지 우리가 시작하면 트랜잭션이 자신:
IF @startingTranCount = 0
COMMIT TRANSACTION
그리고 마지막으로,롤백만의 변경 내용까지:
-- Roll back changes...
IF @startingTranCount > 0
ROLLBACK TRANSACTION MySavePointName
ELSE
ROLLBACK TRANSACTION
다른 팁
장 Brian B 의 응답.
이를 통해 저장 점 이름은 독특하고 사용하는 새로운 시도/CATCH/스의 SQL 서버 2012.
DECLARE @mark CHAR(32) = replace(newid(), '-', '');
DECLARE @trans INT = @@TRANCOUNT;
IF @trans = 0
BEGIN TRANSACTION @mark;
ELSE
SAVE TRANSACTION @mark;
BEGIN TRY
-- do work here
IF @trans = 0
COMMIT TRANSACTION @mark;
END TRY
BEGIN CATCH
IF xact_state() = 1 OR (@trans = 0 AND xact_state() <> 0) ROLLBACK TRANSACTION @mark;
THROW;
END CATCH
내가 사용한 이 유형의 트랜잭션 관리에 저장된 절차:
CREATE PROCEDURE Ardi_Sample_Test
@InputCandidateID INT
AS
DECLARE @TranCounter INT;
SET @TranCounter = @@TRANCOUNT;
IF @TranCounter > 0
SAVE TRANSACTION ProcedureSave;
ELSE
BEGIN TRANSACTION;
BEGIN TRY
/*
<Your Code>
*/
IF @TranCounter = 0
COMMIT TRANSACTION;
END TRY
BEGIN CATCH
IF @TranCounter = 0
ROLLBACK TRANSACTION;
ELSE
IF XACT_STATE() <> -1
ROLLBACK TRANSACTION ProcedureSave;
DECLARE @ErrorMessage NVARCHAR(4000);
DECLARE @ErrorSeverity INT;
DECLARE @ErrorState INT;
SELECT @ErrorMessage = ERROR_MESSAGE();
SELECT @ErrorSeverity = ERROR_SEVERITY();
SELECT @ErrorState = ERROR_STATE();
RAISERROR (@ErrorMessage, @ErrorSeverity, @ErrorState);
END CATCH
GO