关于sqlserver事务出现的一个问题

siuheart 2016-03-17 10:06:08
set @result = 1
begin tran

insert table1(a) values(1)
if @@error!=0
begin
set @result = 2
rollback tran
return
end

insert table2(b) values(2)
if @@error!=0
begin
set @result = 3
rollback tran
return
end

set @result=200
commit tran


运行完后,@result的返回值是200,但最终table1和table2里却没有记录,自增长id是生成的,跟回滚了一样。

运行几年的存储过程,之前一直没出问题,最近偶尔出现了几次,求解,什么情况下会出现这种情况。
...全文
167 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
siuheart 2016-03-18
  • 打赏
  • 举报
回复
程序里没有封装事务,逻辑是这样的: 1、执行存储过程A,成功后往下执行,否则终止页面。 2、出现问题后,我再加了个判断,查询数据库判断记录是否确实插入成功,如果成功,记录自增长id到文本文件,如果失败,终止。 3、 执行一段代码C,成功后继续执行,否则终止 4、C执行成功再执行存储过程B 5、出现问题后,我再加了个判断,查询数据库判断记录是否确实更新成功,如果成功,记录自增长id到文本文件,如果失败,终止。 现在的情况是代码C执行成功了(不涉及数据库操作),A和B的返回值也是显示成功。文本文件里两个id都是有记录的,就是数据库里没有,不知道在什么地方消失了。
中国风 2016-03-18
  • 打赏
  • 举报
回复
在最外层是否封装了事务 把新增A/更新B封装成一个事务了? --造成事务回滚蛋返回值又正常 最好把A/B 合并为一个存储过程 存在时更新,不存在新增,加一个参数ID不传为新增,传时为更新
siuheart 2016-03-18
  • 打赏
  • 举报
回复
一个页面执行两个存储过程,A存储过程执行成功返回200 再执行B,有三张表table1,table2,table3 table1的自增长id与table2的id1字段关联,table3的自增长id与table2的id2字段关联 A 存储过程

set @result = 1
BEGIN TRY

begin tran
set @result = 2
insert table1(a,status) values(1,0)

set @result = 3 
insert table2(b,id1) values(2,@@identity)

set @result=200
commit TRAN
END TRY
BEGIN CATCH
	RAISERROR(N'出错了',16,1)
	ROLLBACK TRAN
END CATCH
B 存储过程

set @result = 1

if not exists(select 1 from table1 where a=1)
begin
	set @result = 20
	return
end

select @id = id from table1 where a=1

if not exists(select 1 from table2 where id1=@id)
begin
	set @result = 21
	return
end

BEGIN TRY

begin tran


set @result = 2
update table1 set status=1 where a=1

set @result = 3
insert table3(c) values(1)

set @result = 4 
update table2 set id2=@@identity  where id1 =  @id 

set @result=200
commit TRAN
END TRY
BEGIN CATCH
	RAISERROR(N'出错了',16,1)
	ROLLBACK TRAN
END CATCH
类似上面这种逻辑,现在情况是AB存储过程都正常返回200 ,出现异常时table1 table2 table3 都没有记录,日志记录自增长id是生成的,但我俩存储过程都没有删除table1和table2的操作,如果table1和table2没记录的话,B存储过程应该都不会执行到事务才是。
siuheart 2016-03-18
  • 打赏
  • 举报
回复
好像不行。。今天又出现了,几分钟内所有运行这个存储过程的都出现问题,版大,还有其他可能出现的情况和解决办法么?
中国风 2016-03-17
  • 打赏
  • 举报
回复
引用 3 楼 siuheart 的回复:
谢谢版本,如果按版主的写法,并发下就不会出现我描述的异常是吗?
对,这样会回滚信息,你要尝试这样去应用,具体还会不会出异常,要看你的环境是否为我猜的这种情况
siuheart 2016-03-17
  • 打赏
  • 举报
回复
谢谢版本,如果按版主的写法,并发下就不会出现我描述的异常是吗?
中国风 2016-03-17
  • 打赏
  • 举报
回复
SQL2005以上版本这样用
set @result = 1
BEGIN TRY

begin tran

set @result = 2
insert table1(a) values(1)


set @result = 3 
insert table2(b) values(2)

 
set @result=200
commit TRAN
END TRY
BEGIN CATCH
	RAISERROR(N'出错了',16,1)
	ROLLBACK TRAN
END CATCH
中国风 2016-03-17
  • 打赏
  • 举报
回复
看方法没问题,并发时可能会出现 最好改写事务
siuheart 2016-03-17
  • 打赏
  • 举报
回复
好的,已经按照版主的代码改过了,我再观察看看,如果还有问题再来,3ks

22,209

社区成员

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

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