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

来源:互联网 发布:和布里兹学画画知乎 编辑:程序博客网 时间:2024/05/17 23:02

最近的项目中遇到两个前端同时去更新一个数据库的表导致数据不完整。

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

1.

--create tableabc(id int);

--go

 

--insertabc(id) values(1);

--set lock_timeout 180

begin tran

 

select *fromabc --with(holdlock);

waitfor delay '00:00:10';

update abcsetid=(selectid+5 from abc )

commit tran;

 

select *fromabc;

2. updateabc set id=8;

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

 

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

3. begin tran

update abcsetid=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  )

0 0
原创粉丝点击