标签:style blog http os io ar strong for 数据
http://www.cnblogs.com/Kymo/archive/2008/05/14/1194161.html
先看一下SQL Server Online Help相关的说明
下面用代码进行解释,代码是根据Online Help Commit Transaction一节的代码修改而成,首先建立一个Table,然后开始三个Trasaction,中间人为触发一些错误,然后观察运行结果。
--Bad code
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)
IF @@ERROR = 0
COMMIT TRANSACTION INNER2;
ELSE
ROLLBACK TRANSACTION ;
INSERT INTO TESTTRAN VALUES (2,‘bbb‘);--Inner1
IF @@ERROR = 0
COMMIT TRANSACTION INNER1;
ELSE
ROLLBACK TRANSACTION ;
INSERT INTO TESTTRAN VALUES (1,‘aaa‘);--OuterTran
--RAISERROR (‘OuterTran error‘,16,1)
IF @@ERROR = 0
COMMIT TRANSACTION OuterTran;
ELSE
ROLLBACK TRANSACTION; 
SELECT * FROM TESTTRAN (NOLOCK);
SELECT @@Trancount;
上述代码当内层事务发生错误时,并不能正常Rollback,因为Rollback把@@Trancount变成了0,所以后面的Commit语句就找不到对应的Transaction了。解决问题的关键就是Rollback时要判断@@Trancount,当@@Trancount等于1时进行Rollback进行回滚,否则执行Commit把@@Trancount-1,同时把@@Error传到外层事务交给外层事务处理。微软的原文是没有问题的,但是这种情况比较简单,我们一眼就能看出哪个是内层事务,哪个是外层事务,一共嵌套了几层,如果是SP调用呢?你不知道你的SP会被谁调用,也不知道会被嵌套几层。
下面看一下怎么处理内层事务的错误(何时Rollback, Commit及错误的传递)
USE NORTHWIND;
--Create test table
IF Object_id(N‘TestTran‘,N‘U‘) IS NOT NULL
DROP TABLE TE
STTRAN;
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)标签:style blog http os io ar strong for 数据
原文地址:http://www.cnblogs.com/SunBlog/p/3961652.html