码迷,mamicode.com
首页 > 数据库 > 详细

SQL Server——事务嵌套

时间:2014-09-09 11:23:18      阅读:279      评论:0      收藏:0      [点我收藏+]

标签:style   blog   http   os   io   ar   strong   for   数据   

http://www.cnblogs.com/Kymo/archive/2008/05/14/1194161.html

 

先看一下SQL Server Online Help相关的说明

  1. Begin Transaction:标记一个显式本地事务的起始点。BEGIN TRANSACTION 使 @@TRANCOUNT 按 1 递增。
  2. Rollback Transaction: 将显式事务或隐性事务回滚到事务的起点或事务内的某个保存点。(嵌套事务时,该语句将所有内层事务回滚到最外面的 BEGIN TRANSACTION 语句。无论在哪种情况下,ROLLBACK TRANSACTION 都将 @@TRANCOUNT 系统函数减小为 0。ROLLBACK TRANSACTION savepoint_name 不减小 @@TRANCOUNT。)
  3. Commit Transaction:标志一个成功的隐性事务或显式事务的结束。如果 @@TRANCOUNT 为 1,COMMIT TRANSACTION 使得自从事务开始以来所执行的所有数据修改成为数据库的永久部分,释放事务所占用的资源,并将 @@TRANCOUNT 减少到 0。如果 @@TRANCOUNT 大于 1,则 COMMIT TRANSACTION 使 @@TRANCOUNT 按 1 递减并且事务将保持活动状态。

下面用代码进行解释,代码是根据Online Help Commit Transaction一节的代码修改而成,首先建立一个Table,然后开始三个Trasaction,中间人为触发一些错误,然后观察运行结果。

 

 

 1bubuko.com,布布扣--Bad code
 2bubuko.com,布布扣USE NORTHWIND;
 3bubuko.com,布布扣--Create test table
 4bubuko.com,布布扣IF Object_id(N‘TestTran‘,N‘U‘) IS NOT NULL
 5bubuko.com,布布扣  DROP TABLE TESTTRAN;
 6bubuko.com,布布扣
 7bubuko.com,布布扣CREATE TABLE TESTTRAN (
 8bubuko.com,布布扣  COLA INT   PRIMARY KEY,
 9bubuko.com,布布扣  COLB CHAR(3));
10bubuko.com,布布扣
11bubuko.com,布布扣--Variable for keeping @@ERROR
12bubuko.com,布布扣DECLARE  @_Error INT;
13bubuko.com,布布扣SET @_Error = 0;
14bubuko.com,布布扣
15bubuko.com,布布扣--Begin 3 nested transaction
16bubuko.com,布布扣BEGIN TRANSACTION OUTERTRAN;
17bubuko.com,布布扣BEGIN TRANSACTION INNER1;
18bubuko.com,布布扣BEGIN TRANSACTION INNER2;
19bubuko.com,布布扣
20bubuko.com,布布扣INSERT INTO TESTTRAN VALUES     (3,‘ccc‘);--Inner2
21bubuko.com,布布扣
22bubuko.com,布布扣RAISERROR(‘Inner2 error‘, 16, 1)
23bubuko.com,布布扣IF @@ERROR = 0
24bubuko.com,布布扣    COMMIT TRANSACTION INNER2;
25bubuko.com,布布扣ELSE
26bubuko.com,布布扣    ROLLBACK TRANSACTION ;
27bubuko.com,布布扣  
28bubuko.com,布布扣INSERT INTO TESTTRAN VALUES     (2,‘bbb‘);--Inner1
29bubuko.com,布布扣
30bubuko.com,布布扣IF @@ERROR = 0
31bubuko.com,布布扣    COMMIT TRANSACTION INNER1;
32bubuko.com,布布扣ELSE
33bubuko.com,布布扣    ROLLBACK TRANSACTION ;
34bubuko.com,布布扣  
35bubuko.com,布布扣INSERT INTO TESTTRAN VALUES     (1,‘aaa‘);--OuterTran
36bubuko.com,布布扣
37bubuko.com,布布扣--RAISERROR (‘OuterTran error‘,16,1)
38bubuko.com,布布扣                        
39bubuko.com,布布扣IF @@ERROR = 0
40bubuko.com,布布扣    COMMIT TRANSACTION OuterTran;
41bubuko.com,布布扣ELSE
42bubuko.com,布布扣    ROLLBACK TRANSACTION;    
43bubuko.com,布布扣
44bubuko.com,布布扣SELECT * FROM   TESTTRAN (NOLOCK);
45bubuko.com,布布扣SELECT @@Trancount;


上述代码当内层事务发生错误时,并不能正常Rollback,因为Rollback把@@Trancount变成了0,所以后面的Commit语句就找不到对应的Transaction了。解决问题的关键就是Rollback时要判断@@Trancount,当@@Trancount等于1时进行Rollback进行回滚,否则执行Commit把@@Trancount-1,同时把@@Error传到外层事务交给外层事务处理。微软的原文是没有问题的,但是这种情况比较简单,我们一眼就能看出哪个是内层事务,哪个是外层事务,一共嵌套了几层,如果是SP调用呢?你不知道你的SP会被谁调用,也不知道会被嵌套几层。

下面看一下怎么处理内层事务的错误(何时Rollback, Commit及错误的传递)

 

 1--Good code
 2bubuko.com,布布扣USE NORTHWIND;
 3bubuko.com,布布扣
 4bubuko.com,布布扣--Create test table
 5bubuko.com,布布扣IF Object_id(N‘TestTran‘,N‘U‘) IS NOT NULL
 6bubuko.com,布布扣  DROP TABLE TE
bubuko.com,布布扣STTRAN;
 7bubuko.com,布布扣
 8bubuko.com,布布扣CREATE TABLE TESTTRAN (
 9bubuko.com,布布扣  COLA INT   PRIMARY KEY,
10bubuko.com,布布扣  COLB CHAR(3));
11bubuko.com,布布扣
12bubuko.com,布布扣--Variable for keeping @@ERROR
13bubuko.com,布布扣DECLARE  @_Error INT;
14bubuko.com,布布扣SET @_Error = 0;
15bubuko.com,布布扣
16bubuko.com,布布扣--Begin 3 nested transaction
17bubuko.com,布布扣BEGIN TRANSACTION OUTERTRAN;
18bubuko.com,布布扣BEGIN TRANSACTION INNER1;
19bubuko.com,布布扣BEGIN TRANSACTION INNER2;
20bubuko.com,布布扣
21bubuko.com,布布扣INSERT INTO TESTTRAN VALUES     (3,‘ccc‘);--Inner2
22bubuko.com,布布扣
23bubuko.com,布布扣--raiserror(‘Inner2 error‘, 16, 1)
24bubuko.com,布布扣SET    @_Error = @@ERROR              
25bubuko.com,布布扣IF    @_Error = 0
26bubuko.com,布布扣    COMMIT TRAN INNER2;
27bubuko.com,布布扣ELSE
28bubuko.com,布布扣  IF @@TRANCOUNT > 1
29bubuko.com,布布扣    COMMIT TRANSACTION INNER2;
30bubuko.com,布布扣  ELSE
31bubuko.com,布布扣       ROLLBACK TRANSACTION INNER2;
32bubuko.com,布布扣  
33bubuko.com,布布扣INSERT INTO TESTTRAN VALUES     (2,‘bbb‘);--Inner1
34bubuko.com,布布扣
35bubuko.com,布布扣IF @_Error = 0
36bubuko.com,布布扣    SET @_Error = @@ERROR                
37bubuko.com,布布扣IF @_Error = 0
38bubuko.com,布布扣    COMMIT TRAN INNER1;
39bubuko.com,布布扣ELSE
40bubuko.com,布布扣  IF @@TRANCOUNT > 1
41bubuko.com,布布扣    COMMIT TRANSACTION INNER1;
42bubuko.com,布布扣  ELSE
43bubuko.com,布布扣    ROLLBACK TRANSACTION INNER1;
44bubuko.com,布布扣  
45bubuko.com,布布扣INSERT INTO TESTTRAN VALUES     (1,‘aaa‘);--OuterTran
46bubuko.com,布布扣
47bubuko.com,布布扣RAISERROR (‘OuterTran error‘,16,1)
48bubuko.com,布布扣
49bubuko.com,布布扣--    rollback transaction OuterTran
50bubuko.com,布布扣SET @_Error = @_Error + @@ERROR
51bubuko.com,布布扣                        
52bubuko.com,布布扣IF @_Error = 0
53bubuko.com,布布扣    COMMIT TRAN OUTERTRAN;
54bubuko.com,布布扣ELSE
55bubuko.com,布布扣    IF @@TRANCOUNT > 1
56bubuko.com,布布扣        COMMIT TRANSACTION;
57bubuko.com,布布扣    ELSE
58bubuko.com,布布扣        ROLLBACK TRANSACTION OUTERTRAN;    
59bubuko.com,布布扣
60bubuko.com,布布扣SELECT * FROM   TESTTRAN (NOLOCK)

SQL Server——事务嵌套

标签:style   blog   http   os   io   ar   strong   for   数据   

原文地址:http://www.cnblogs.com/SunBlog/p/3961652.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!