问题描述:
在对一个玩家充值时,如果此时玩家不在线,内存中也没有缓存数据,此时需要从db(先从redis中查询,如果未命中,则去mysql中获取)中读取玩家数据,记录readdb1。由于有充值活动,活动的配置数据是在一个redis服务中读取的,记录为readrdb2,读取成功后根据两次读取结果操作剩余逻辑。 问题就出在这里。
如下流程:
skynet.call(readdb1()) --阻塞式读取
拿到玩家参与活动flag
skynet.call(readrdb2()) --阻塞式读取
if 玩家还未参与过活动flag==0
给玩家发送活动礼包
end
setflag flag=1 //非阻塞式,设置已经参加过活动标识
givemoney //非阻塞式,给钱
;以上流程当readrdb2阻塞等待时(这个redis服务繁忙),此时如果有第二笔充值订单进来,拿到的flag仍为0未参加活动,这就会导致重复赠送玩家礼包。
所以在一个逻辑里面,有多个call时,要注意这样的并发问题。至于这个问题的解决办法很简单:在本服务中,永久记录一个玩家的活动状态就好了,就是读内存数据
网友评论