2011-12-18 139 views
1

我有兩個步驟:TSQL交易 - 提交和回滾

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? 

回答

3

當您的過程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. 

你可能也想看看文章nesting transactions

1
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