日期:2014-05-16  浏览次数:20684 次

关于sqlserver是否回滚的问题,,,,,
就是一个简单的过程

DECLARE @docstatus int  
SELECT @docstatus=docstatus  
FROM fardoc WITH (NOLOCK)  
WHERE DocCode=@doccode  
IF @docstatus=100 -------这里100代表单据已确认状态 
BEGIN   
insert into 表1(字段省略)  
select  字段省略
from 表2 with (nolock)  
where doccode=@doccode  
END  
ELSE  
BEGIN  
 RAISERROR('插入子帐失败!',16,1)  
 RETURN   
END
  

现在的问题是,数据插入了表1,且单据状态不是100,,,
这种情况如何跟踪处理?
------解决方案--------------------
改成这样试试:

DECLARE @docstatus int  
SELECT @docstatus=docstatus  
FROM fardoc WITH (NOLOCK)  
WHERE DocCode=@doccode  
IF @docstatus=100 -------这里100代表单据已确认状态 
BEGIN   
insert into 表1(字段省略)  
select  字段省略
from 表2 with (nolock)  
where doccode=@doccode  
END  
ELSE  
BEGIN  
 RAISERROR('插入子帐失败!',16,1)  
  rollback   --这里回滚
 RETURN   
END

------解决方案--------------------
没有用事务不会回滚,但这个代码上来看条件是已经成立了,有可能是更新成100以后又给更新回去了,或者没有更新成功的时候就脏读了。为什么你这里每个查询都写nolock?
------解决方案--------------------
引用:
Quote: 引用:

没有用事务不会回滚,但这个代码上来看条件是已经成立了,有可能是更新成100以后又给更新回去了,或者没有更新成功的时候就脏读了。为什么你这里每个查询都写nolock?


因为这几个表有大量查询,,,怕锁,,,我估计也是更新成100以后又给更新回去了,没有更新成功的时候就脏读了(这种不知道,因为没见过实际发生过的情况),现在就是不知道怎么解决,,,

你读到脏100
执行了插入 
然后这脏100由于某种原因又回滚了
------解决方案--------------------
引用:
Quote: 引用:

Quote: 引用:

Quote: 引用:

没有用事务不会回滚,但这个代码上来看条件是已经成立了,有可能是更新成100以后又给更新回去了,或者没有更新成功的时候就脏读了。为什么你这里每个查询都写nolock?


因为这几个表有大量查询,,,怕锁,,,我估计也是更新成100以后又给更新回去了,没有更新成功的时候就脏读了(这种不知道,因为没见过实际发生过的情况),现在就是不知道怎么解决,,,

你读到脏100
执行了插入 
然后这脏100由于某种原因又回滚了


意思是说,我现在去掉with (nolock) ? 


把with (nolock)去去掉试试。

另外,你的存储过程,如果@docstatus<>100,那么要回滚,这个是回滚什么呢,好像从代码来看,没有任何操作是需要回滚的。

你的意思,是不是回滚执行这个存储过程之前的,操作呢?