Q:

TSQL transaction - commit and rollback

I have two procedure:
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

When I call P1 I got:
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.

I expected result like this:
1
1
2
1

My questions are:
1. Why do I got this error?

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

A:

When your Procedure P2 executes the rollback line, you are rolling back the outer-most transaction. (The one originally created in P1)  This changes the transaction count from the time before P2 was called, until after it was executed.
If you expect a procedure to affect the transaction count, you could call the procedure in a Try-Catch to be able to handle the informational message you get back.
From 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.

You may also want to look at the article on nesting transactions.

