code

EXECUTE 이후 트랜잭션 수는 BEGIN 및 COMMIT 문의 일치하지 않는 수를 나타냅니다.

codestyles 2020. 10. 7. 07:40
반응형

EXECUTE 이후 트랜잭션 수는 BEGIN 및 COMMIT 문의 일치하지 않는 수를 나타냅니다. 이전 카운트 = 1, 현재 카운트 = 0


Table1에 데이터를 공급하고 Table1에서 Column1 값을 가져오고 Table2를 공급할 두 번째 저장 프로 시저를 호출하는 Insert Stored Procedure가 있습니다.

그러나 두 번째 저장 프로 시저를 다음과 같이 호출하면

Exec USPStoredProcName

다음과 같이 오류가 발생합니다.

EXECUTE 이후 트랜잭션 수는 BEGIN 및 COMMIT 문의 일치하지 않는 수를 나타냅니다. 이전 카운트 = 1, 현재 카운트 = 0.

나는 다른 질문에 대한 답변을 읽었으며 정확히 커밋 수가 엉망이되는 곳을 찾을 수 없습니다.


TRY / CATCH 블록이있는 경우 가능한 원인은 트랜잭션 중단 예외를 포착하고 계속하는 것입니다. CATCH 블록에서는 항상 XACT_STATE()적절한 중단 및 커밋 할 수없는 (두꺼운) 트랜잭션을 확인 하고 처리 해야 합니다. 호출자가 트랜잭션을 시작하고 calee가 교착 상태 (트랜잭션을 중단 함)에 도달하면 호출 수신자가 트랜잭션이 중단되었으며 '평상시처럼 비즈니스'를 계속해서는 안된다는 것을 호출자에게 어떻게 전달할 것인가? 가능한 유일한 방법은 예외를 다시 발생시켜 호출자가 상황을 처리하도록하는 것입니다. 중단 된 트랜잭션을 조용히 삼키고 호출자가 계속해서 원래 트랜잭션에 있다고 가정하면 신체 상해 만이 보장 할 수 있습니다 (그리고 발생하는 오류는 엔진이 자체 보호를 시도하는 방식입니다).

중첩 트랜잭션 및 예외와 함께 사용할 수있는 패턴을 보여주는 예외 처리 및 중첩 트랜잭션살펴볼 것을 권장합니다 .

create procedure [usp_my_procedure_name]
as
begin
    set nocount on;
    declare @trancount int;
    set @trancount = @@trancount;
    begin try
        if @trancount = 0
            begin transaction
        else
            save transaction usp_my_procedure_name;

        -- Do the actual work here

lbexit:
        if @trancount = 0
            commit;
    end try
    begin catch
        declare @error int, @message varchar(4000), @xstate int;
        select @error = ERROR_NUMBER(), @message = ERROR_MESSAGE(), @xstate = XACT_STATE();
        if @xstate = -1
            rollback;
        if @xstate = 1 and @trancount = 0
            rollback
        if @xstate = 1 and @trancount > 0
            rollback transaction usp_my_procedure_name;

        raiserror ('usp_my_procedure_name: %d: %s', 16, 1, @error, @message) ;
    end catch
end
go

나도이 문제가 있었다. 저에게 이유는 제가하고 있었기 때문입니다

return
commit

대신에

commit
return   

하나의 저장 프로 시저에서.


이것은 일반적으로 트랜잭션이 시작되고 커밋되지 않았거나 롤백되지 않을 때 발생합니다.

저장 프로 시저에 오류가 발생하는 경우 예외 처리없이 일부 런타임 오류로 인해 트랜잭션이 완료되지 않아 데이터베이스 테이블을 잠글 수 있습니다. 아래와 같이 예외 처리를 사용할 수 있습니다. SET XACT_ABORT

SET XACT_ABORT ON
SET NoCount ON
Begin Try 
     BEGIN TRANSACTION 
        //Insert ,update queries    
     COMMIT
End Try 
Begin Catch 
     ROLLBACK
End Catch

출처


중첩 된 트랜잭션을 사용하는 경우 ROLLBACK 작업은 가장 바깥쪽에있는 트랜잭션을 포함하여 모든 중첩 된 트랜잭션을 롤백합니다.

This might, with usage in combination with TRY/CATCH, result in the error you described. See more here.


This can also occur if your stored procedure encounters a compile failure after opening a transaction (e.g. table not found, invalid column name).

I found i had to use 2 stored procedures a "worker" one and a wrapper one with try/catch both with logic similar to that outlined by Remus Rusanu. The worker catch is used to handle the "normal" failures and the wrapper catch to handle compile failure errors.

https://msdn.microsoft.com/en-us/library/ms175976.aspx

Errors Unaffected by a TRY…CATCH Construct

The following types of errors are not handled by a CATCH block when they occur at the same level of execution as the TRY…CATCH construct:

  • Compile errors, such as syntax errors, that prevent a batch from running.
  • Errors that occur during statement-level recompilation, such as object name resolution errors that occur after compilation because of deferred name resolution.

Hopefully this helps someone else save a few hours of debugging...


I had the same error message, my mistake was that I had a semicolon at the end of COMMIT TRANSACTION line


I encountered this error once after omitting this statement from my transaction.

COMMIT TRANSACTION [MyTransactionName]

Make sure you don't have multiple transactions in the same procedure/query out of which one or more are left uncommited.

In my case, I accidentally had a BEGIN TRAN statement in the query


This can also depend on the way you are invoking the SP from your C# code. If the SP returns some table type value then invoke the SP with ExecuteStoreQuery, and if the SP doesn't returns any value invoke the SP with ExecuteStoreCommand


For me after extensive debugging the fix was a simple missing throw; statement in the catch after the rollback. Without it this ugly error message is what you end up with.

begin catch
    if @@trancount > 0 rollback transaction;
    throw; --allows capture of useful info when an exception happens within the transaction
end catch

In my opinion the accepted answer is in most cases an overkill.

The cause of the error is often mismatch of BEGIN and COMMIT as clearly stated by the error. This means using:

Begin
  Begin
    -- your query here
  End
commit

instead of

Begin Transaction
  Begin
    -- your query here
  End
commit

omitting Transaction after Begin causes this error!


If you are having a code structure of something like:

SELECT 151
RETURN -151

Then use:

SELECT 151
ROLLBACK
RETURN -151

참고URL : https://stackoverflow.com/questions/21930156/transaction-count-after-execute-indicates-a-mismatching-number-of-begin-and-comm

반응형