문제

는 저장 프로시저를 사용하고 있는 요구를 설정 포인트를 저장할 수 있도록 특정 상황에서,모든 사항을 취소했고 오류를 반환하는 코드를 호출자 또는 받아들이는지를 확고 성공을 반환하여 발신번호를 입력하실 수 있습니다.그러나 나는 그것을 필요로 작동하는지 여부를 호출자는 이미 트랜잭션을 시작하거나지 않습니다.문서가 매우 혼란에서이다.여기에 내가 무엇을 생각하는 것입니다 작업을,하지만 나는 특정의 모든 효과.

일-이 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  
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top