Commit ef434138 authored by tangtuo's avatar tangtuo

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

parent 94363fad
...@@ -29,7 +29,7 @@ public class RedisConstant { ...@@ -29,7 +29,7 @@ public class RedisConstant {
/** /**
* 纪念版nft领取成员列表 * 纪念版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; ...@@ -22,6 +22,7 @@ import com.fzm.common.utils.JsonUtil;
import com.fzm.common.utils.RedisUtil; import com.fzm.common.utils.RedisUtil;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.redisson.api.RLock;
import org.redisson.api.RSemaphore; import org.redisson.api.RSemaphore;
import org.redisson.api.RedissonClient; import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
...@@ -103,11 +104,19 @@ public class CommemorateNftServiceImpl extends ServiceImpl<CommemorateNftMapper, ...@@ -103,11 +104,19 @@ public class CommemorateNftServiceImpl extends ServiceImpl<CommemorateNftMapper,
@Override @Override
public Boolean receive(Integer id) { 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); CommemorateNft commemorateNft = getById(id);
if (commemorateNft == null) { if (commemorateNft == null) {
throw GlobalException.newException(ResultCode.DATA_ERROR, "没找到此纪念版nft详情,请稍后再试"); throw GlobalException.newException(ResultCode.DATA_ERROR, "没找到此纪念版nft详情,请稍后再试");
} }
User user = userService.getUserByToken();
// 先判断当前用户有没有领取过此纪念版nft // 先判断当前用户有没有领取过此纪念版nft
if (redisUtil.sIsMember(RedisConstant.COMMEMORATE_NFT_MEMBERS_PREFIX + id, user.getId().toString())) { if (redisUtil.sIsMember(RedisConstant.COMMEMORATE_NFT_MEMBERS_PREFIX + id, user.getId().toString())) {
throw GlobalException.newException(ResultCode.FAILED, "此纪念版nft每个用户只能领取一次"); throw GlobalException.newException(ResultCode.FAILED, "此纪念版nft每个用户只能领取一次");
...@@ -153,6 +162,10 @@ public class CommemorateNftServiceImpl extends ServiceImpl<CommemorateNftMapper, ...@@ -153,6 +162,10 @@ public class CommemorateNftServiceImpl extends ServiceImpl<CommemorateNftMapper,
// 领取完毕,把当前用户id加入到纪念版nft的领取记录中 // 领取完毕,把当前用户id加入到纪念版nft的领取记录中
redisUtil.sAdd(RedisConstant.COMMEMORATE_NFT_MEMBERS_PREFIX + id, user.getId().toString()); redisUtil.sAdd(RedisConstant.COMMEMORATE_NFT_MEMBERS_PREFIX + id, user.getId().toString());
return true; return true;
} finally {
lock.unlock();
}
} }
public static void main(String[] args) { 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