Microsoft TechNet「トランザクションのネスト」にて簡潔に説明されているので引用させていただきます。
@@TRANCOUNTのカウント(ざっくり)
- BEGIN TRANSACTION ステートメントは @@TRANCOUNT を 1 ずつ増やします。
- COMMIT TRANSACTION は @@TRANCOUNT を 1 ずつ減らします。
- ROLLBACK TRANSACTION ステートメントは、ネストしたトランザクションがすべてロールバックされ、@@TRANCOUNT は 0 になります。
- @@TRANCOUNT が 0 の場合は、トランザクションにいません。
http://technet.microsoft.com/ja-jp/library/aa213076(SQL.80).aspx
トランザクションの外側と内側の概念、超重要!
Microsoft SQL Server は、内部トランザクションのコミットを無視します。
トランザクションは、最も外側のトランザクションが終了したときの処理に基づいてコミットまたはロールバックされます。
外側のトランザクションがコミットされた場合、ネストした内部トランザクションもコミットされます。
外側のトランザクションがロールバックされた場合、内部トランザクションが個々にコミットされているかどうかに関係なく、内部トランザクションもすべてがロールバックされます。
http://technet.microsoft.com/ja-jp/library/aa213076(SQL.80).aspx
つまり一番外側のコミット/ロールバックに依存するということです。
※部分的にロールバックしたい場合はセーブポイントを使用します。
図説およびサンプルコード(英語)
http://www.vfpconversion.com/Article.aspx?quickid=0305111
内側のトランザクションのエラー処理などはクセがあるので上記のサンプルコードを参考にされると良いでしょう。
具体的には「内側のトランザクションではROLLBACKは発行せずにCOMMITで終了して戻り値で判断する。そしてROLLBACKは外側のトランザクションで行う。」です。
-- Normal exit
IF @@TRANCOUNT > 0
COMMIT
RETURN(0)
-- Error Exit
ErrExit:
IF @@TRANCOUNT > 1
COMMIT
ELSE
IF @@TRANCOUNT = 1
ROLLBACK
RETURN(-1)
参考:
SQL Server 2000でのコネクション/トランザクション問題
http://d.hatena.ne.jp/PoohKid/20060608/p2