您的位置:首页 > 其它

如何避免不同应用更改数据,导致的数据不一致。

2015-08-02 11:42 405 查看
最近的项目中遇到两个前端同时去更新一个数据库的表导致数据不完整。

分析原因是一个更新使用了事务,另一个更新没有使用事务。做了一个测试代码如下:

1.
--create tableabc(id int);
--go
 
--insertabc(id) values(1);
--set lock_timeout 180
begin tran
 
select *from
abc --with(holdlock);
waitfor
delay '00:00:10';
update abcset
id=(selectid
+5 from
abc )
commit tran;
 
select *from
abc;
2. updateabc
set id=8;

先从1开始执行,然后执行2..得到的结果是13.说明,虽然1先执行,但由于阻塞,2先通过了。因此结果是13.这不是我们希望的结果。去掉注释后,得到正确的结果8..

 

我们将2使用事务处理。改成3,同进注释掉1中的with(holdlock),再执行

3. begin
tran
update abcset
id=8;
commit tran;

得到的结果是13.说明1由于阻塞,2先通过。说明两个不同的事务,也可能出现第二个事务先被更新的情况。因此解决这个问题最理想的方式是人为加锁。使用 holdlock.但默认为这个锁会一直等,直到获取共享锁。我们不希望它一直这样等下去。因此在储存过程的开头加上 lock_timeout .这个参数是以毫秒为单位的。

另,如果事务处理过长,不愿意另外进程等待的时间 过多,可以用下来的语句来做一个锁定,在需要处理的数据之前。

if exists(select * from abc b with (holdlock) left join orders r on r.收购合同号=b.id  )
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: