[sql] SQL Server-트랜잭션이 오류로 롤백됩니까?

다음과 같은 SQL Server 2005에서 일부 SQL을 실행하는 클라이언트 앱이 있습니다.

BEGIN TRAN;
INSERT INTO myTable (myColumns ...) VALUES (myValues ...);
INSERT INTO myTable (myColumns ...) VALUES (myValues ...);
INSERT INTO myTable (myColumns ...) VALUES (myValues ...);
COMMIT TRAN;

하나의 긴 문자열 명령으로 전송됩니다.

삽입 중 하나가 실패하거나 명령의 일부가 실패하면 SQL Server가 트랜잭션을 롤백합니까? 롤백되지 않으면 롤백하기 위해 두 번째 명령을 보내야합니까?

사용중인 API 및 언어에 대한 세부 정보를 제공 할 수 있지만 SQL Server는 모든 언어에 대해 동일하게 응답해야한다고 생각합니다.



답변

set xact_abort on트랜잭션이 발생하면 오류 발생시 SQL이 자동으로 롤백되도록 할 수 있습니다 .


답변

전체 트랜잭션이 롤백 될 것입니다. 명령을 실행하여 롤백해야합니다.

TRY CATCH다음과 같이 이것을 블록으로 감쌀 수 있습니다

BEGIN TRY
    BEGIN TRANSACTION

        INSERT INTO myTable (myColumns ...) VALUES (myValues ...);
        INSERT INTO myTable (myColumns ...) VALUES (myValues ...);
        INSERT INTO myTable (myColumns ...) VALUES (myValues ...);

    COMMIT TRAN -- Transaction Success!
END TRY
BEGIN CATCH
    IF @@TRANCOUNT > 0
        ROLLBACK TRAN --RollBack in case of Error

    -- you can Raise ERROR with RAISEERROR() Statement including the details of the exception
    RAISERROR(ERROR_MESSAGE(), ERROR_SEVERITY(), 1)
END CATCH


답변

다음은 MSSQL Server 2016에서 작동하는 오류 메시지가 나오는 코드입니다.

BEGIN TRY
    BEGIN TRANSACTION
        -- Do your stuff that might fail here
    COMMIT
END TRY
BEGIN CATCH
    IF @@TRANCOUNT > 0
        ROLLBACK TRAN

        DECLARE @ErrorMessage NVARCHAR(4000) = ERROR_MESSAGE()
        DECLARE @ErrorSeverity INT = ERROR_SEVERITY()
        DECLARE @ErrorState INT = ERROR_STATE()

    -- Use RAISERROR inside the CATCH block to return error  
    -- information about the original error that caused  
    -- execution to jump to the CATCH block.  
    RAISERROR (@ErrorMessage, @ErrorSeverity, @ErrorState);
END CATCH


답변

MDSN 기사에서 트랜잭션 제어 (데이터베이스 엔진) .

제약 조건 위반과 같은 런타임 문 오류가 일괄 처리로 발생하면 데이터베이스 엔진의 기본 동작은 오류를 생성 한 문만 롤백하는 것입니다. SET XACT_ABORT 문을 사용하여이 동작을 변경할 수 있습니다. SET XACT_ABORT ON이 실행 된 후 런타임 명령문 오류로 인해 현재 트랜잭션이 자동 롤백됩니다. 구문 오류와 같은 컴파일 오류는 SET XACT_ABORT의 영향을받지 않습니다. 자세한 내용은 SET XACT_ABORT (Transact-SQL)를 참조하십시오.

귀하의 경우 삽입 중 하나라도 실패하면 전체 트랜잭션을 롤백합니다.


답변

삽입 중 하나가 실패하거나 명령의 일부가 실패하면 SQL Server가 트랜잭션을 롤백합니까?

아니 그렇지 않아.

롤백되지 않으면 롤백하기 위해 두 번째 명령을 보내야합니까?

물론, ROLLBACK대신 발행해야합니다 COMMIT.

트랜잭션을 커미트 또는 롤백할지 여부를 결정 COMMIT하려면 명령문 에서 문장을 제거 하고 삽입 결과를 점검 한 후 점검 결과에 따라 COMMIT또는 ROLLBACK결과 를 발행 해야합니다.


답변