来源:http://blog.chinaunix.net/uid-20476365-id-3179250.html
先看一下SQL Server Online Help相关的说明
- Begin Transaction:标记一个显式本地事务的起始点。BEGIN TRANSACTION 使 @@TRANCOUNT 按 1 递增。
- Rollback Transaction: 将显式事务或隐性事务回滚到事务的起点或事务内的某个保存点。(嵌套事务时,该语句将所有内层事务回滚到最外面的 BEGIN TRANSACTION 语句。无论在哪种情况下,ROLLBACK TRANSACTION 都将 @@TRANCOUNT 系统函数减小为 0。ROLLBACK TRANSACTION savepoint_name 不减小 @@TRANCOUNT。)
- Commit Transaction: 标志一个成功的隐性事务或显式事务的结束。如果 @@TRANCOUNT 为 1,COMMIT TRANSACTION 使得自从事务开始以来所执行的所有数据修改成为数据库的永久部分,释放事务所占用的资源,并将 @@TRANCOUNT 减少到 0。如果 @@TRANCOUNT 大于 1,则 COMMIT TRANSACTION 使 @@TRANCOUNT 按 1 递减并且事务将保持活动状态。
- Sample
USE NORTHWIND;
--Create test table
IF Object_id(N'TestTran',N'U') IS NOT NULL
DROP TABLE TESTTRAN;
CREATE TABLE TESTTRAN (
COLA INT PRIMARY KEY,
COLB CHAR(3));
--Variable for keeping @@ERROR
DECLARE @_Error INT;
SET @_Error = 0;
--Begin 3 nested transaction
BEGIN TRANSACTION OUTERTRAN;
BEGIN TRANSACTION INNER1;
BEGIN TRANSACTION INNER2;
INSERT INTO TESTTRAN VALUES (3,'ccc');--Inner2
--raiserror('Inner2 error', 16, 1)
SET @_Error = @@ERROR
IF @_Error = 0
COMMIT TRAN INNER2;
ELSE
IF @@TRANCOUNT > 1
COMMIT TRANSACTION INNER2;
ELSE
ROLLBACK TRANSACTION INNER2;
INSERT INTO TESTTRAN VALUES (2,'bbb');--Inner1
IF @_Error = 0
SET @_Error = @@ERROR
IF @_Error = 0
COMMIT TRAN INNER1;
ELSE
IF @@TRANCOUNT > 1
COMMIT TRANSACTION INNER1;
ELSE
ROLLBACK TRANSACTION INNER1;
INSERT INTO TESTTRAN VALUES (1,'aaa');--OuterTran
RAISERROR ('OuterTran error',16,1)
-- rollback transaction OuterTran
SET @_Error = @_Error + @@ERROR
IF @_Error = 0
COMMIT TRAN OUTERTRAN;
ELSE
IF @@TRANCOUNT > 1
COMMIT TRANSACTION;
ELSE
ROLLBACK TRANSACTION OUTERTRAN;
SELECT * FROM TESTTRAN (NOLOCK)
- Save Transaction:事务保存点,用于回滚部分事务的机制,它不会对@@TRANCOUNT产生任何影响,
只是标记回滚事务可以达到的点,可以通过它来进行回滚内部事务 - --定义一个是否为嵌套事务的标志
DECLARE @nestedFlag Bit
if (@@trancount>0)
BEGIN
--是嵌套事务,使用保存点,避免再次嵌套
SET @nestedFlag=1
SAVE TRAN TESTA
END
ELSE
BEGIN
--不是嵌套:开启一个事务
SET @nestedFlag = 0
BEGIN TRAN TESTA
END
--执行业务操作,如果出错就回滚事务,并立即返回
IF(@@error<>0)
BEGIN
ROLLBACK TRAN TestA
RETURN 0
END
--如果不是嵌套事务才提交
IF(@nestedFlag=0)
BEGIN
COMMIT TRAN TESTA
END