Commit ef434138 authored by tangtuo's avatar tangtuo

解决同一个用户可以并发领取纪念版nft的问题

parent 94363fad
......@@ -29,7 +29,7 @@ public class RedisConstant {
/**
* 纪念版nft领取成员列表
*/
public static final String COMMEMORATE_NFT_MEMBERS_PREFIX = "commemorateNft:members";
public static final String COMMEMORATE_NFT_MEMBERS_PREFIX = "commemorateNft:members:";
......
......@@ -22,6 +22,7 @@ import com.fzm.common.utils.JsonUtil;
import com.fzm.common.utils.RedisUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.redisson.api.RLock;
import org.redisson.api.RSemaphore;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Value;
......@@ -103,11 +104,19 @@ public class CommemorateNftServiceImpl extends ServiceImpl<CommemorateNftMapper,
@Override
public Boolean receive(Integer id) {
User user = userService.getUserByToken();
// 加锁,避免一个用户可以并发领取
RLock lock = redisson.getLock("receive:nft:" + user.getId());
boolean tryLock = lock.tryLock();
if (!tryLock){
throw GlobalException.newException(ResultCode.RECEIVE_ERROR, "操作频繁");
}
try {
CommemorateNft commemorateNft = getById(id);
if (commemorateNft == null) {
throw GlobalException.newException(ResultCode.DATA_ERROR, "没找到此纪念版nft详情,请稍后再试");
}
User user = userService.getUserByToken();
// 先判断当前用户有没有领取过此纪念版nft
if (redisUtil.sIsMember(RedisConstant.COMMEMORATE_NFT_MEMBERS_PREFIX + id, user.getId().toString())) {
throw GlobalException.newException(ResultCode.FAILED, "此纪念版nft每个用户只能领取一次");
......@@ -153,6 +162,10 @@ public class CommemorateNftServiceImpl extends ServiceImpl<CommemorateNftMapper,
// 领取完毕,把当前用户id加入到纪念版nft的领取记录中
redisUtil.sAdd(RedisConstant.COMMEMORATE_NFT_MEMBERS_PREFIX + id, user.getId().toString());
return true;
} finally {
lock.unlock();
}
}
public static void main(String[] args) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment