事宜中@@TRANCOUNT值的疑问
事务中@@TRANCOUNT值的疑问?
看文章说@@TRANCOUNT的初始值为0,begin transaction 后+1, commit transaction 后变为0。我测试了发现每个位置@@TRANCOUNT的值都是2.这是为什么啊?
上面代码执行后@@TRANCOUNT值结果如下(TestValue 表的内容)
值 序号
2 1
2 4
上面的rollback的,下面这段是有commit,显示还是都是2
上面COMMIT这段代码执行后@@TRANCOUNT值结果如下(TestValue 表的内容)
值 序号
2 1
2 2
2 3
------解决方案--------------------
呵呵,确实有定奇怪。
我觉得是不是这样的:
首先,在一个批处理中,比如在执行一个存储过程时,就开始了1个事务,然后在存储过程中,再执行insert语句时,开始了一个新的事务,因为insert语句单独执行时,就是一个事务,所以这个时候就是2.
然后,还有一个问题是,如果你在你的存储过程中,直接执行一个:
select @@trancount 那么总是返回0,这是因为这个语句由于是select语句,所以就没有单独成1个事务。
这个只是我的大概的猜测。
------解决方案--------------------
我把你的insert语句全部替换成print,得到的结果是你希望值,应该是insert本身就是一个自动提交的事务的原因。
------解决方案--------------------
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数值不准。
------解决方案--------------------
你打开了sql server的隐性事物,所以2个,你去掉就好了,隐形事物一点也不实用,而且很麻烦。
------解决方案--------------------
这篇文章解释的很详细。
看文章说@@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
------解决方案--------------------
呵呵,确实有定奇怪。
我觉得是不是这样的:
首先,在一个批处理中,比如在执行一个存储过程时,就开始了1个事务,然后在存储过程中,再执行insert语句时,开始了一个新的事务,因为insert语句单独执行时,就是一个事务,所以这个时候就是2.
然后,还有一个问题是,如果你在你的存储过程中,直接执行一个:
select @@trancount 那么总是返回0,这是因为这个语句由于是select语句,所以就没有单独成1个事务。
这个只是我的大概的猜测。
------解决方案--------------------
我把你的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
*/
------解决方案--------------------
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数值不准。
------解决方案--------------------
你打开了sql server的隐性事物,所以2个,你去掉就好了,隐形事物一点也不实用,而且很麻烦。
------解决方案--------------------
这篇文章解释的很详细。