事务中@@TRANCOUNT值的疑问?

yilin54 2014-01-12 04:14:08
看文章说@@TRANCOUNT的初始值为0,begin transaction 后+1, commit transaction 后变为0。我测试了发现每个位置@@TRANCOUNT的值都是2.这是为什么啊?

create procedure test_pro
as
begin
--insert into TestValue 这个相当于记录@@TRANCOUNT的值,我用print在查询分析器里看不到。
insert into TestValue values(@@TRANCOUNT,'1') --这里还没开始@@TRANCOUNT应该是0,实际结果是2
begin transaction
insert into TestValue values(@@TRANCOUNT,'2') --这里事务刚开始@@TRANCOUNT应该是1,实际结果是2
insert into Student values('998888','小马哥','国际贸易','99086')

insert into TestValue values(@@TRANCOUNT,'3') --这里@@TRANCOUNT应该还是1,实际结果是2
rollback transaction
insert into TestValue values(@@TRANCOUNT,'4') --这里回滚了,@@TRANCOUNT应该由1变为0了,实际结果还是2
end


上面代码执行后@@TRANCOUNT值结果如下(TestValue 表的内容)
值 序号
2 1
2 4



上面的rollback的,下面这段是有commit,显示还是都是2

create procedure test_pro
as
begin

insert into TestValue values(@@TRANCOUNT,'1') --这里还没开始@@TRANCOUNT应该是0,实际结果是2
begin transaction
insert into TestValue values(@@TRANCOUNT,'2') --这里事务刚开始@@TRANCOUNT应该是1,实际结果是2
insert into Student values('998888','小马哥','国际贸易','99086')
commit transaction
insert into TestValue values(@@TRANCOUNT,'3') --这里提交事务了,@@TRANCOUNT应该由1变为0了,实际结果还是2
end

上面COMMIT这段代码执行后@@TRANCOUNT值结果如下(TestValue 表的内容)
值 序号
2 1
2 2
2 3
...全文
968 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
發糞塗牆 2014-01-14
  • 打赏
  • 举报
回复
我的是2012哦,2000应该有@@trancount吧?单独一句print @@trancount能出来不?
yilin54 2014-01-14
  • 打赏
  • 举报
回复
引用 2 楼 DBA_Huangzj 的回复:
我把你的insert语句全部替换成print,得到的结果是你希望值,应该是insert本身就是一个自动提交的事务的原因。
ALTER procedure  test_pro
as
begin
--insert into TestValue 这个相当于记录@@TRANCOUNT的值,我用print在查询分析器里看不到。
PRINT @@TRANCOUNT --这里还没开始@@TRANCOUNT应该是0,实际结果是2
begin transaction
PRINT @@TRANCOUNT
 
PRINT @@TRANCOUNT --这里@@TRANCOUNT应该还是1,实际结果是2
rollback transaction
PRINT @@TRANCOUNT --这里回滚了,@@TRANCOUNT应该由1变为0了,实际结果还是2
END


EXEC test_pro


/*
0
1
1
0

*/
为什么我用print,查询分析器里没有不出来啊。我用的是sql2000
sundayzhao 2014-01-13
  • 打赏
  • 举报
回复
你打开了sql server的隐性事物,所以2个,你去掉就好了,隐形事物一点也不实用,而且很麻烦。
KevinLiu 2014-01-13
  • 打赏
  • 举报
回复
create procedure test_pro as begin declare @int int set @int = @@TRANCOUNT --insert into TestValue 这个相当于记录@@TRANCOUNT的值,我用print在查询分析器里看不到。 insert into testvalue values(@int,'1') --这里还没开始@@TRANCOUNT应该是0,实际结果是2 begin transaction set @int = @@TRANCOUNT insert into testvalue values(@int,'2') --这里事务刚开始@@TRANCOUNT应该是1,实际结果是2 set @int = @@TRANCOUNT insert into testvalue values(@int,'3') --这里@@TRANCOUNT应该还是1,实际结果是2 rollback transaction set @int = @@TRANCOUNT insert into testvalue values(@int,'4') --这里回滚了,@@TRANCOUNT应该由1变为0了,实际结果还是2 end 提一下如果你想记录@@trancount的值保存在本地变量里面使用,不能用在INSERT的插入里面,因为INSERT也是事物,会导致trancount数值不准。
發糞塗牆 2014-01-13
  • 打赏
  • 举报
回复
我把你的insert语句全部替换成print,得到的结果是你希望值,应该是insert本身就是一个自动提交的事务的原因。
ALTER procedure  test_pro
as
begin
--insert into TestValue 这个相当于记录@@TRANCOUNT的值,我用print在查询分析器里看不到。
PRINT @@TRANCOUNT --这里还没开始@@TRANCOUNT应该是0,实际结果是2
begin transaction
PRINT @@TRANCOUNT
 
PRINT @@TRANCOUNT --这里@@TRANCOUNT应该还是1,实际结果是2
rollback transaction
PRINT @@TRANCOUNT --这里回滚了,@@TRANCOUNT应该由1变为0了,实际结果还是2
END


EXEC test_pro


/*
0
1
1
0

*/
KevinLiu 2014-01-13
  • 打赏
  • 举报
回复
http://blogs.msdn.com/b/jenss/archive/2010/07/10/usage-of-trancount-in-dml-statements.aspx
KevinLiu 2014-01-13
  • 打赏
  • 举报
回复
这篇文章解释的很详细。
  • 打赏
  • 举报
回复
呵呵,确实有定奇怪。 我觉得是不是这样的: 首先,在一个批处理中,比如在执行一个存储过程时,就开始了1个事务,然后在存储过程中,再执行insert语句时,开始了一个新的事务,因为insert语句单独执行时,就是一个事务,所以这个时候就是2. 然后,还有一个问题是,如果你在你的存储过程中,直接执行一个: select @@trancount 那么总是返回0,这是因为这个语句由于是select语句,所以就没有单独成1个事务。 这个只是我的大概的猜测。

22,209

社区成员

发帖
与我相关
我的任务
社区描述
MS-SQL Server 疑难问题
社区管理员
  • 疑难问题社区
  • 尘觉
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧