Транзакция TSQL - фиксация и откат - PullRequest
1 голос
/ 18 декабря 2011

У меня есть две процедуры:

create procedure P2
as
begin
    print @@trancount
    begin tran

    if 1 = 1
    begin
          print @@trancount
          rollback
    end
    else
    begin
          commit
    end
end
go


create procedure P1
as
begin
    begin tran
        print @@trancount
        exec P2
        print @@trancount
    commit
end
go

exec P1

Когда я звоню P1, я получил:

1
1
2
Msg 266, Level 16, State 2, Procedure P2, Line 0
Transaction count after EXECUTE indicates a mismatching number of BEGIN and COMMIT statements. Previous count = 1, current count = 0.
0
Msg 3902, Level 16, State 1, Procedure P1, Line 8
The COMMIT TRANSACTION request has no corresponding BEGIN TRANSACTION.

Я ожидал такой результат:

1
1
2
1

Мои вопросыявляются:

1. Why do I got this error?

2. How should I write my procedure to do it good?

Ответы [ 2 ]

3 голосов
/ 18 декабря 2011

Когда ваша Процедура P2 выполняет строку rollback, вы откатываете самую внешнюю транзакцию. (Первоначально созданный в P1). Это изменяет количество транзакций со времени до вызова P2 и до его выполнения.

Если вы ожидаете, что процедура повлияет на количество транзакций, вы можете вызвать процедуру в Try-Catch , чтобы иметь возможность обрабатывать возвращаемое вами информационное сообщение.

С MSDN :

In stored procedures, ROLLBACK TRANSACTION statements without a savepoint_name
or transaction_name roll back all statements to the outermost BEGIN TRANSACTION.
A ROLLBACK TRANSACTION statement in a stored procedure that causes @@TRANCOUNT
to have a different value when the stored procedure completes than the
@@TRANCOUNT value when the stored procedure was called produces an informational
message. This message does not affect subsequent processing.

Возможно, вы захотите взглянуть на статью о вложенных транзакциях .

1 голос
/ 19 декабря 2011
alter procedure P2 as 
    begin  
           print @@trancount 
               IF @@TRANCOUNT > 0
                        BEGIN
                            save tran SAVEPOINT1
                        END
                        ELSE
                        BEGIN 
                         begin tran
                        END 
                     if 1 = 1    
                     begin  
                            print @@trancount
                            IF XACT_STATE() <> -1
                            BEGIN
                                rollback tran SAVEPOINT1        
                            END

                     end
                            else
                        begin  
                         commit   
                      end 
            end 
    go 
alter procedure P1 
    as 
    begin
            begin tran
            print @@trancount                                    
            exec P2     
            print @@trancount    
            commit 
    end 
go
 exec P1    
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...