表A
字段:
a_id(主键)
totalquantity(int类型/B表quantity字段值的sum汇总)
表B
字段:
b_id(主键)
a_id(外键)
quantity(int类型)
-----------------------------------------
处理程序的伪代码如下:
function buyadd(id,quantity)
{
变量 m=执行查询语句(select totalquantity from a where a_id=id) //获取目前总数量
变量 n=执行查询语句(select sum(quantity) from b where a_id=id) //获取数量汇总
if(m-n>0)
{
执行语句(insert into b(b_id,a_id,quantity)values(b_id,id,quantity));
return true;
}
return false;
}
========================================================
好了问题出现了,就是当执行buyadd方法时,一旦是多用户访问的情况下很容易读出赃数据,造成多插入的问题。
(比如2个用户同时读取的时候都发现m-n>0,然后就都insert, 直接就导致n<m的情况出现)
也想过select的时候加锁,但是会引起并发延迟的问题,请问大家都怎么处理这个问题的呢?
------解决思路----------------------
可否设置等待延时?第一个用户读取后,延时几秒钟,第二个用户再读取数据应该就不会出现这种情况了!
------解决思路----------------------
你不和将要插入的quantity比较?单人更新也会导致 n>m 的啊!
建议a表加个remainquantity 字段,表示还可以添加的数量。
下面用SQL描述,你自己翻译成对应的程序。
BEGIN TRAN
update a
set remainquantity = remainquantity - @quantity
where a_id=id
and remainquantity >= @quantity -- 这个很关键
IF @@ROWCOUNT=0
BEGIN
ROLLBACK TRAN
END
ELSE
BEGIN
insert into b(b_id,a_id,quantity)values(b_id,id,@quantity))
COMMIT TRAN
END
原理参考类似问题的帖子sql事务
------解决思路----------------------
类似问题面对并发的时候,只有也只能通过加锁来解决
楼主参考下具体的加锁方法
http://www.cnblogs.com/nzperfect/archive/2011/09/27/2193143.html#2973795