Microsoft MVP성태의 닷넷 이야기
글쓴 사람
정성태 (techsharer at outlook.com)
홈페이지
첨부 파일
 

Transaction count after EXECUTE indicates a mismatching number of BEGIN and COMMIT statements. Previous count = 0, current count = 1.

이런 오류가 발생하는군요.

System.Data.SqlClient.SqlException (0x80131904): Transaction count after EXECUTE indicates a mismatching number of BEGIN and COMMIT statements. Previous count = 0, current count = 1.
at System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction)
at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj, Boolean callerHasConnectionLock, Boolean asyncClose)
at System.Data.SqlClient.TdsParser.TryRun(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj, Boolean& dataReady)
at System.Data.SqlClient.SqlDataReader.TryConsumeMetaData()
at System.Data.SqlClient.SqlDataReader.get_MetaData()
at System.Data.SqlClient.SqlCommand.FinishExecuteReader(SqlDataReader ds, RunBehavior runBehavior, String resetOptionsString, Boolean isInternal, Boolean forDescribeParameterEncryption, Boolean shouldCacheForAlwaysEncrypted)
at System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, Boolean async, Int32 timeout, Task& task, Boolean asyncWrite, Boolean inRetry, SqlDataReader ds, Boolean describeParameterEncryptionRequest)
at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method, TaskCompletionSource`1 completion, Int32 timeout, Task& task, Boolean& usedCache, Boolean asyncWrite, Boolean inRetry)
at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method)
at System.Data.SqlClient.SqlCommand.ExecuteReader(CommandBehavior behavior, String method)
ClientConnectionId:be105026-4697-4300-a0c8-e393b642ed68
Error Number:266,State:2,Class:16
SQL: ...[sql query]...

간단하게 재현을 해볼까요? 다음과 같이 SP를 만들고,

CREATE PROCEDURE uspTest
AS
BEGIN
    BEGIN TRANSACTION 
        SELECT  1 / 0
END

실행하면 동일한 오류가 발생합니다.

EXEC uspTest

Msg 8134, Level 16, State 1, Procedure uspTest, Line 5 [Batch Start Line 0]
Divide by zero error encountered.
Msg 266, Level 16, State 2, Procedure uspTest, Line 0 [Batch Start Line 0]
Transaction count after EXECUTE indicates a mismatching number of BEGIN and COMMIT statements. Previous count = 0, current count = 1.

즉, 트랜잭션이 열리고 닫힌 쌍이 맞지 않는 경우 저런 오류가 발생하는 것입니다. 반면 어떤 식으로든 COMMIT 또는 ROLLBACK을 하면,

CREATE PROCEDURE uspTest
AS
BEGIN
    BEGIN TRANSACTION 
        SELECT  1 / 0
        COMMIT  -- 또는 ROLLBACK
END

오류 메시지는 이제 다음과 같습니다.

Msg 8134, Level 16, State 1, Procedure uspTest, Line 5 [Batch Start Line 0]
Divide by zero error encountered.




여기서 재미있는 것은, BEGIN TRANSACTION 이후 나오는 모든 SQL 쿼리의 예외가 저런 식으로 처리되는 것은 아니라는 점입니다. 가령 존재하지 않는 테이블을 다루는 SQL을 실행한다면,

CREATE PROCEDURE uspTest
AS
BEGIN
    BEGIN TRANSACTION 
        SELECT * FROM abc12345
        COMMIT
END

이번에는 그 SQL 쿼리 이후의 구문(위의 경우 COMMIT)이 실행되지 않아 다시 처음과 같은 오류가 발생합니다.

Msg 208, Level 16, State 1, Procedure uspTest, Line 5 [Batch Start Line 0]
Invalid object name 'abc12345'.
Msg 266, Level 16, State 2, Procedure uspTest, Line 5 [Batch Start Line 0]
Transaction count after EXECUTE indicates a mismatching number of BEGIN and COMMIT statements. Previous count = 0, current count = 1.

이런 경우 만약 트랜잭션 처리를 하고 싶다면 "SET XACT_ABORT ON;"을 넣어주면 됩니다.

CREATE PROCEDURE uspTest
AS
BEGIN
    SET XACT_ABORT ON;

    BEGIN TRANSACTION 
        SELECT * FROM abc12345
        COMMIT
END

저런 식으로 쿼리 실행 후 다음 쿼리로 진행하지 않고 실패하는 경우는 TRY / CATCH로도 잡히지 않습니다. 가령, 첫 번째 쿼리는 다음과 같은 식으로 COMMIT/ROLLBACK을 처리할 수 있지만,

CREATE PROCEDURE uspTest
AS
BEGIN
    BEGIN TRANSACTION 
        BEGIN TRY
            SELECT  1 / 0 -- 이 코드의 예외는 CATCH로 잡히므로,
            COMMIT
        END TRY
        BEGIN CATCH
            ROLLBACK   -- 트랜잭션이 ROLLBACK 됨.
        END CATCH
END

이렇게 아예 처리 자체를 종료하는 구문 오류는,

CREATE PROCEDURE uspTest
AS
BEGIN
    BEGIN TRANSACTION 
		BEGIN TRY
			SELECT * FROM abc12345 -- 이 코드의 오류로 SP 실행 자체가 중지됨
			COMMIT -- 이 코드도 실행되지 않고,
		END TRY
		BEGIN CATCH
			ROLLBACK -- 이 코드도 실행되지 않음
		END CATCH
END

CATCH에 잡히지 않으므로 마찬가지로 (COMMIT은 물론) ROLLBACK이 실행되지 않아 동일하게 "Transaction count after EXECUTE indicates a mismatching number of BEGIN and COMMIT statements. Previous count = 0, current count = 1." 오류가 발생합니다.




[이 글에 대해서 여러분들과 의견을 공유하고 싶습니다. 틀리거나 미흡한 부분 또는 의문 사항이 있으시면 언제든 댓글 남겨주십시오.]







[최초 등록일: ]
[최종 수정일: 5/24/2020]

Creative Commons License
이 저작물은 크리에이티브 커먼즈 코리아 저작자표시-비영리-변경금지 2.0 대한민국 라이센스에 따라 이용하실 수 있습니다.
by SeongTae Jeong, mailto:techsharer at outlook.com

비밀번호

댓글 작성자
 




... 16  17  18  19  20  21  22  [23]  24  25  26  27  28  29  30  ...
NoWriterDateCnt.TitleFile(s)
13055정성태5/11/20229403.NET Framework: 2008. C# - async/await 그리고 스레드 (1) MyTask로 재현 [11]파일 다운로드1
13054정성태5/11/20226881.NET Framework: 2007. C# - 10진수 숫자를 담은 문자열을 숫자로 변환하는 방법 [11]파일 다운로드1
13053정성태5/10/20226540.NET Framework: 2006. C# - GC.KeepAlive 메서드의 역할
13052정성태5/9/20226554.NET Framework: 2005. C# - 생성한 참조 개체가 언제 GC의 정리 대상이 될까요?
13051정성태5/8/20226512.NET Framework: 2004. C# XingAPI - ACF 검색 결과로 구한 CSV 파일을 통해 퀀트 종목 찾기파일 다운로드1
13050정성태5/6/20226542.NET Framework: 2003. C# - COM 개체의 이벤트 핸들러에서 발생하는 예외에 대한 CLR의 특별 대우파일 다운로드1
13049정성태5/6/20225517오류 유형: 811. GoLand - Error: Cannot find package
13048정성태5/6/20226645오류 유형: 810. "ASUS TUF GAMING B550M-PLUS (WI-FI)" 모델에서 블루투스 장치가 인식이 안 되는 문제
13047정성태5/6/20226618오류 유형: 809. Speech Recognition could not start
13046정성태5/5/20226934.NET Framework: 2002. C# XingAPI - ACF 파일을 이용한 퀀트 종목 찾기(t1857)
13045정성태5/5/20226982.NET Framework: 2001. C# XingAPI - 주식 종목에 따른 PBR, PER, ROE 구하는 방법(t3341 예제)
13044정성태5/4/20226429오류 유형: 808. error : clang++ exited with code 127
13043정성태5/3/20226092오류 유형: 807. C# - 닷넷 응용 프로그램에서 Informix DB 사용 시 오류 메시지 정리
13042정성태5/3/20226457.NET Framework: 2000. C# - 닷넷 응용 프로그램에서 Informix DB 사용 방법파일 다운로드1
13041정성태4/28/20226739개발 환경 구성: 642. Informix 데이터베이스 docker 환경 구성
13040정성태4/27/20227242VC++: 156. 비주얼 스튜디오 - Linux C/C++ 프로젝트에서 openssl 링크하는 방법
13039정성태4/27/20228054.NET Framework: 1999. C# - Playwright를 이용한 간단한 브라우저 제어 실습
13038정성태4/26/20225925오류 유형: 806. twine 실행 시 ConfigParser.ParsingError: File contains parsing errors: /root/.pypirc
13037정성태4/25/20226245.NET Framework: 1998. Azure Functions를 사용한 간단한 실습
13036정성태4/24/20227002.NET Framework: 1997. C# - nano 시간을 가져오는 방법 [2]
13035정성태4/22/20227578Windows: 204. Windows 10부터 바뀐 QueryPerformanceFrequency, QueryPerformanceCounter
13034정성태4/21/20226947.NET Framework: 1996. C# XingAPI - 주식 종목에 따른 PBR, PER, ROE, ROA 구하는 방법(t3320, t8430 예제)파일 다운로드1
13033정성태4/18/20227569.NET Framework: 1195. C# - Thread.Yield와 Thread.Sleep(0)의 차이점(?)
13032정성태4/17/20227283오류 유형: 805. Github의 50MB 파일 크기 제한 - warning: GH001: Large files detected. You may want to try Git Large File Storage
13031정성태4/15/20226807.NET Framework: 1194. C# - IdealProcessor와 ProcessorAffinity의 차이점
13030정성태4/15/20226496오류 유형: 804. 정규 표현식 오류 - Quantifier {x,y} following nothing.
... 16  17  18  19  20  21  22  [23]  24  25  26  27  28  29  30  ...