我的数据库中有个表,字段如下:
CREATE TABLE [tab1] (
[id] [int] IDENTITY (1, 1) NOT NULL ,
[value] [int] NULL ,
[name] [varchar] (50) COLLATE Chinese_PRC_CI_AS NULL ,
CONSTRAINT [PK_tab1] PRIMARY KEY  CLUSTERED 
(
[id]
)  ON [PRIMARY] 
) ON [PRIMARY]
GO然后我写了一段脚本来测试嵌套事务的问题:begin transaction t
begin tran t_1    --第一次写入数据
insert tab1(value,name)
select 1,'1'
commit tran t_1
save tran s_1 begin tran t_2    --第二次写入数据
insert tab1(value,name)
select '2h','2' if @@error!=0
begin
print('rollback tran s_1')
rollback tran s_1
end
else
commit tran t_2
commit tran t
理论上在执行到“第二次写入数据”时候出错就应该回滚到“s_1”,那么结果就只插入了一条数据,但是现在是如何测试都发现没有插入任何记录。后来我还把代码改为下面两种代码也不行:
第一种:
begin transaction t
begin tran t_1    --第一次写入数据
insert tab1(value,name)
select 1,'1'
commit tran t_1
save tran s_1 begin tran t_2    --第二次写入数据
insert tab1(value,name)
select '2h','2' if @@error!=0
begin
print('rollback tran t_2')
rollback tran t_2
end
else
commit tran t_2
commit tran t
第二种:
begin transaction t
begin tran t_1    --第一次写入数据
insert tab1(value,name)
select 1,'1'
commit tran t_1
save tran t_1 begin tran t_2    --第二次写入数据
insert tab1(value,name)
select '2h','2' if @@error!=0
begin
print('rollback tran t_1')
rollback tran t_1
end
else
commit tran t_2
commit tran t

解决方案 »

  1.   

    >>dutguoyi(新鲜鱼排) 还是不行!代码如下:begin transaction t
    begin tran t_1 --第一次写入数据
    insert tab1(value,name)
    select 1,'1'
    commit tran t_1 begin tran t_2 --第二次写入数据
    save tran s_2
    insert tab1(value,name)
    select '2h','2' if @@error!=0
    begin
    print('rollback tran s_2')
    rollback tran s_2
    end
    else
    commit tran t_2
    commit tran t
      

  2.   

    SQL Server 2000里面的帮助文档是如下描述的:
    ROLLBACK TRANSACTION 语句的 transaction_name 参数引用一组命名的嵌套事务的内层事务是非法的,transaction_name 只能引用最外部事务的事务名。如果在一组嵌套事务的任意级别执行使用外部事务名称的 ROLLBACK TRANSACTION transaction_name 语句,那么所有的嵌套事务都将回滚。如果在一组嵌套事务的任意级别执行没有 transaction_name 参数的 ROLLBACK WORK 或 ROLLBACK TRANSACTION 语句,那么它将回滚所有嵌套事务,包括最外部事务。从中可以看出内层的事务的回滚应该是直接回滚到了最外层的事务开头。