并发扣款一致性,幂等性问题
《并发扣款,如何保证数据的一致性?》,分享了同一个用户并发扣款时,有一定概率出现数据不一致,可以使用CAS乐观锁的方式,在不降低吞吐量,并且只有少量修改的情况下,保证数据的一致性。
文章发布不到24小时,就有近200的评论。
UPDATE t_yue SET money=$new_money WHERE uid=$uid AND money=$old_money;
UPDATE t_yue SET money=money-$diff WHERE uid=$uid;
UPDATE t_yue SET money=money-$diff WHERE uid=$uid AND money-$diff>0;
UPDATE t_yue SET money=money-$diff WHERE uid=$uid AND money>$diff;
bool RegisterUser($uid, $name){
//查看uid是否已经存在
select uid from t_user where uid=$uid;
//不是新用户,返回失败
if(rows>0)return false;
else{
bool TestCase_RegisterUser(){
//造一些假数据
long uid=123;
String name='shenjian';
//调用被测试的接口
bool result= RegisterUser(uid,name);
//预期注册成功,对结果进行断言判断
Assert(result,true);
//返回测试结果
return result;
}
这个用例存在什么问题?
bool TestCase_RegisterUser(){
//造一些假数据
long uid=123;
String name=’shenjian’;
//先删除这个伪造的用户
DeleteUser(uid);
//调用被测试的接口
bool result= RegisterUser(uid,name);
//预期注册成功,对结果进行断言判断
Assert(result,true);
//返回测试结果
return result;
}
-
insert x,一般来说不是幂等的,重复插入得到的结果不一定一样
-
delete x,一般来说是幂等的,删除多次得到的结果仍相同
-
set a=x是幂等的
-
set a=a-x不是幂等的
-
…
result = DoSomething();
if(false==result || TIMEOUT){
//错误,或者超时,重试一次
result= DoSomething();
}
return result;
-
select&set,配合CAS方案
-
set money-=X方案