create procedure P_level1
as
begin
begin tran
print '调用前事务级:%1!',@@trancount
execute P_level2
print '调用后事务级:%1!',@@trancount
commit tran
end
create procedure P_level2
as
begin
begin tran
print '调用中事务级:%1!',@@trancount
rollback tran
end
输出结果如下:
调用前事务级:1
调用中事务级:2
Server Message: Number 266, Severity 10
Transaction count after EXECUTE indicates that a COMMIT or ROLLBACK TRAN is missing. Previous count = 1, Current count = 0.
调用后事务级:0
执行存储过程时sybase对打开的事务进行计数。运行存储过程前后事务数若不相等则产生266号错误。但据Sybase事务机制,嵌套事务中任一层回滚时,回滚至第一层。从而在P_level2中回滚后事务数为0,与调用前的1不符。
该问题如何解决?是否在sybase嵌套存储过程中子过程不予许回滚,只能设置一个output参数,判断出错时用该参数返回错误代码,用commit平衡事务数,return,然后在*事务中判断output参数值,若出错则回滚。也就是说,Sybase只能在*事务中回滚,若多级存储过程嵌套,须一级一级上传返回值?
太繁琐了吧,请高手指点
7 个解决方案
#1
帮你顶!
#2
记住一个规则:
1、在事务中的任何一个没有名字的rollback tran会将@@trancount置为0,也就是所有的变化全部回滚;
2、在事务中的commit tran会将@@trancount减1,知道commit到@@trancount=0时才提交;
1、在事务中的任何一个没有名字的rollback tran会将@@trancount置为0,也就是所有的变化全部回滚;
2、在事务中的commit tran会将@@trancount减1,知道commit到@@trancount=0时才提交;
#3
你可以这么写:
create procedure P_level1
as
begin
begin tran
print '调用前事务级:%1!',@@trancount
execute P_level2
print '调用后事务级:%1!',@@trancount
commit tran
end
create procedure P_level2
as
begin
if @@trancount > 0
save tran aa
else
begin tran aa
print '调用中事务级:%1!',@@trancount
rollback tran aa
end
create procedure P_level1
as
begin
begin tran
print '调用前事务级:%1!',@@trancount
execute P_level2
print '调用后事务级:%1!',@@trancount
commit tran
end
create procedure P_level2
as
begin
if @@trancount > 0
save tran aa
else
begin tran aa
print '调用中事务级:%1!',@@trancount
rollback tran aa
end
#4
tolison兄:
我记得sybase在非*事务中是不允许带名字回滚的吧?在P_level2中用
rollback tran aa
同样会出错的
我记得sybase在非*事务中是不允许带名字回滚的吧?在P_level2中用
rollback tran aa
同样会出错的
#5
虽然事务可以嵌套,但是只能回退最外层的事务
#6
存储过程中的事务回退,可以回退到save tran 事物名称的地方,如果没有命名事务,将回退到调用存储过程地方的第一个begin tran.
tolison应该是对的
tolison应该是对的
#7
这样写没有问题
drop procedure P_level1
create procedure P_level1
as
begin
begin tran tran1
print '调用前事务级:%1!',@@trancount
execute P_level2
if @@error >0
begin
select '执行过程错误'
rollback tran tran1
return
end
print '调用后事务级:%1!',@@trancount
commit tran tran1
print '提交后事务级:%1!',@@trancount
end
create procedure P_level2
as
begin
begin tran
print '调用中事务级:%1!',@@trancount
if @@error >0
begin
select '执行过程错误'
rollback tran tran1
return
end
commit tran
end
exec P_level1
drop procedure P_level1
create procedure P_level1
as
begin
begin tran tran1
print '调用前事务级:%1!',@@trancount
execute P_level2
if @@error >0
begin
select '执行过程错误'
rollback tran tran1
return
end
print '调用后事务级:%1!',@@trancount
commit tran tran1
print '提交后事务级:%1!',@@trancount
end
create procedure P_level2
as
begin
begin tran
print '调用中事务级:%1!',@@trancount
if @@error >0
begin
select '执行过程错误'
rollback tran tran1
return
end
commit tran
end
exec P_level1
#1
帮你顶!
#2
记住一个规则:
1、在事务中的任何一个没有名字的rollback tran会将@@trancount置为0,也就是所有的变化全部回滚;
2、在事务中的commit tran会将@@trancount减1,知道commit到@@trancount=0时才提交;
1、在事务中的任何一个没有名字的rollback tran会将@@trancount置为0,也就是所有的变化全部回滚;
2、在事务中的commit tran会将@@trancount减1,知道commit到@@trancount=0时才提交;
#3
你可以这么写:
create procedure P_level1
as
begin
begin tran
print '调用前事务级:%1!',@@trancount
execute P_level2
print '调用后事务级:%1!',@@trancount
commit tran
end
create procedure P_level2
as
begin
if @@trancount > 0
save tran aa
else
begin tran aa
print '调用中事务级:%1!',@@trancount
rollback tran aa
end
create procedure P_level1
as
begin
begin tran
print '调用前事务级:%1!',@@trancount
execute P_level2
print '调用后事务级:%1!',@@trancount
commit tran
end
create procedure P_level2
as
begin
if @@trancount > 0
save tran aa
else
begin tran aa
print '调用中事务级:%1!',@@trancount
rollback tran aa
end
#4
tolison兄:
我记得sybase在非*事务中是不允许带名字回滚的吧?在P_level2中用
rollback tran aa
同样会出错的
我记得sybase在非*事务中是不允许带名字回滚的吧?在P_level2中用
rollback tran aa
同样会出错的
#5
虽然事务可以嵌套,但是只能回退最外层的事务
#6
存储过程中的事务回退,可以回退到save tran 事物名称的地方,如果没有命名事务,将回退到调用存储过程地方的第一个begin tran.
tolison应该是对的
tolison应该是对的
#7
这样写没有问题
drop procedure P_level1
create procedure P_level1
as
begin
begin tran tran1
print '调用前事务级:%1!',@@trancount
execute P_level2
if @@error >0
begin
select '执行过程错误'
rollback tran tran1
return
end
print '调用后事务级:%1!',@@trancount
commit tran tran1
print '提交后事务级:%1!',@@trancount
end
create procedure P_level2
as
begin
begin tran
print '调用中事务级:%1!',@@trancount
if @@error >0
begin
select '执行过程错误'
rollback tran tran1
return
end
commit tran
end
exec P_level1
drop procedure P_level1
create procedure P_level1
as
begin
begin tran tran1
print '调用前事务级:%1!',@@trancount
execute P_level2
if @@error >0
begin
select '执行过程错误'
rollback tran tran1
return
end
print '调用后事务级:%1!',@@trancount
commit tran tran1
print '提交后事务级:%1!',@@trancount
end
create procedure P_level2
as
begin
begin tran
print '调用中事务级:%1!',@@trancount
if @@error >0
begin
select '执行过程错误'
rollback tran tran1
return
end
commit tran
end
exec P_level1