Showing
1 changed file
with
24 additions
and
10 deletions
@@ -2,6 +2,7 @@ package com.yohoufo.promotion.service.impl; | @@ -2,6 +2,7 @@ package com.yohoufo.promotion.service.impl; | ||
2 | 2 | ||
3 | import com.google.common.collect.Lists; | 3 | import com.google.common.collect.Lists; |
4 | import com.google.common.collect.Range; | 4 | import com.google.common.collect.Range; |
5 | +import com.yoho.core.redis.cluster.operations.serializer.RedisKeyBuilder; | ||
5 | import com.yoho.error.ServiceError; | 6 | import com.yoho.error.ServiceError; |
6 | import com.yoho.error.exception.ServiceException; | 7 | import com.yoho.error.exception.ServiceException; |
7 | import com.yohobuy.ufo.model.promotion.UserCouponsBo; | 8 | import com.yohobuy.ufo.model.promotion.UserCouponsBo; |
@@ -14,6 +15,9 @@ import com.yohobuy.ufo.model.promotion.request.UserCouponListReq; | @@ -14,6 +15,9 @@ import com.yohobuy.ufo.model.promotion.request.UserCouponListReq; | ||
14 | import com.yohobuy.ufo.model.promotion.response.CouponInfo; | 15 | import com.yohobuy.ufo.model.promotion.response.CouponInfo; |
15 | import com.yohobuy.ufo.model.promotion.response.CouponInfoListBo; | 16 | import com.yohobuy.ufo.model.promotion.response.CouponInfoListBo; |
16 | import com.yohobuy.ufo.model.promotion.response.CouponSendBo; | 17 | import com.yohobuy.ufo.model.promotion.response.CouponSendBo; |
18 | +import com.yohoufo.common.exception.UfoServiceException; | ||
19 | +import com.yohoufo.common.lock.RedisLock; | ||
20 | +import com.yohoufo.common.lock.RedisLockFactory; | ||
17 | import com.yohoufo.common.utils.DateUtil; | 21 | import com.yohoufo.common.utils.DateUtil; |
18 | import com.yohoufo.dal.promotion.CouponMapper; | 22 | import com.yohoufo.dal.promotion.CouponMapper; |
19 | import com.yohoufo.dal.promotion.UserCouponMapper; | 23 | import com.yohoufo.dal.promotion.UserCouponMapper; |
@@ -32,6 +36,7 @@ import java.time.LocalDateTime; | @@ -32,6 +36,7 @@ import java.time.LocalDateTime; | ||
32 | import java.time.LocalTime; | 36 | import java.time.LocalTime; |
33 | import java.time.ZoneOffset; | 37 | import java.time.ZoneOffset; |
34 | import java.util.*; | 38 | import java.util.*; |
39 | +import java.util.concurrent.TimeUnit; | ||
35 | import java.util.function.Function; | 40 | import java.util.function.Function; |
36 | import java.util.stream.Collectors; | 41 | import java.util.stream.Collectors; |
37 | 42 | ||
@@ -53,6 +58,9 @@ public class CouponServiceImpl implements ICouponService { | @@ -53,6 +58,9 @@ public class CouponServiceImpl implements ICouponService { | ||
53 | @Autowired | 58 | @Autowired |
54 | SingleCentCouponService singleCentSyncCoupNumService; | 59 | SingleCentCouponService singleCentSyncCoupNumService; |
55 | 60 | ||
61 | + @Autowired | ||
62 | + private RedisLockFactory redisLockFactory; | ||
63 | + | ||
56 | 64 | ||
57 | private final Logger logger = LoggerFactory.getLogger(getClass()); | 65 | private final Logger logger = LoggerFactory.getLogger(getClass()); |
58 | 66 | ||
@@ -181,10 +189,10 @@ public class CouponServiceImpl implements ICouponService { | @@ -181,10 +189,10 @@ public class CouponServiceImpl implements ICouponService { | ||
181 | logger.warn("query coupon info,coupontype is null:{}", couponToken); | 189 | logger.warn("query coupon info,coupontype is null:{}", couponToken); |
182 | throw new ServiceException(ServiceError.PROMOTION_COUPON_HAS_NOT_EXISTS); | 190 | throw new ServiceException(ServiceError.PROMOTION_COUPON_HAS_NOT_EXISTS); |
183 | } | 191 | } |
184 | - | 192 | + RedisLock redisLock = null; |
185 | if(!repeatable){ | 193 | if(!repeatable){ |
186 | // 校验是否可以领取(重复领取,时间是否合法,状态) | 194 | // 校验是否可以领取(重复领取,时间是否合法,状态) |
187 | - checkCanAcquire(uid, couponToken, couponAndType); | 195 | + redisLock = checkCanAcquire(uid, couponToken, couponAndType); |
188 | } | 196 | } |
189 | 197 | ||
190 | if (couponAndType.getCoupon().getStatus() != CouponsStatusEnum.VALID.getCode()){ | 198 | if (couponAndType.getCoupon().getStatus() != CouponsStatusEnum.VALID.getCode()){ |
@@ -208,19 +216,16 @@ public class CouponServiceImpl implements ICouponService { | @@ -208,19 +216,16 @@ public class CouponServiceImpl implements ICouponService { | ||
208 | } | 216 | } |
209 | 217 | ||
210 | int count = 0; | 218 | int count = 0; |
211 | - // 不可重复 | ||
212 | - if (!repeatable){ | ||
213 | - count = userCouponMapper.insertWhere(userCoupon); | ||
214 | - }else{ | ||
215 | - count = userCouponMapper.insert(userCoupon); | ||
216 | - } | ||
217 | - | 219 | + count = userCouponMapper.insert(userCoupon); |
218 | if (count == 0){ | 220 | if (count == 0){ |
219 | logger.info("can not repeatable acquire coupon. uid is {}, coupon is {}", uid, couponToken); | 221 | logger.info("can not repeatable acquire coupon. uid is {}, coupon is {}", uid, couponToken); |
220 | throw new ServiceException(ServiceError.PROMOTION_COUPON_HAS_RECEIVED); | 222 | throw new ServiceException(ServiceError.PROMOTION_COUPON_HAS_RECEIVED); |
221 | } | 223 | } |
222 | 224 | ||
223 | logger.info("senCoupon success,{},{},{},{}", uid, couponToken, couponCode, count); | 225 | logger.info("senCoupon success,{},{},{},{}", uid, couponToken, couponCode, count); |
226 | + if(Objects.nonNull(redisLock)){ | ||
227 | + redisLock.unlock(); | ||
228 | + } | ||
224 | return couponCode; | 229 | return couponCode; |
225 | } | 230 | } |
226 | 231 | ||
@@ -317,13 +322,22 @@ public class CouponServiceImpl implements ICouponService { | @@ -317,13 +322,22 @@ public class CouponServiceImpl implements ICouponService { | ||
317 | } | 322 | } |
318 | 323 | ||
319 | 324 | ||
320 | - private void checkCanAcquire(Integer uid, String couponToken, CouponAndType couponAndType) { | 325 | + private RedisLock checkCanAcquire(Integer uid, String couponToken, CouponAndType couponAndType) { |
321 | // 验证该用户是否重复领取 | 326 | // 验证该用户是否重复领取 |
322 | UserCoupon userCoupon = userCouponMapper.selectByUidAndToken(uid, couponToken); | 327 | UserCoupon userCoupon = userCouponMapper.selectByUidAndToken(uid, couponToken); |
328 | + | ||
329 | + RedisLock redisLock = redisLockFactory.newLock(RedisKeyBuilder.newInstance() | ||
330 | + .appendFixed("ufo:promotion:coupons:checkCanAcquire:") | ||
331 | + .appendVar(uid + "-" + couponToken), 3, TimeUnit.SECONDS); | ||
332 | + if (!redisLock.tryLock()) { | ||
333 | + logger.info("{} checkCanAcquire fail, it already in the process", uid); | ||
334 | + throw new UfoServiceException(400, "优惠券领取中"); | ||
335 | + } | ||
323 | if (userCoupon != null){ | 336 | if (userCoupon != null){ |
324 | logger.warn("user has acquried this coupon before:{},{}", uid, couponToken); | 337 | logger.warn("user has acquried this coupon before:{},{}", uid, couponToken); |
325 | throw new ServiceException(ServiceError.PROMOTION_COUPON_HAS_RECEIVED); | 338 | throw new ServiceException(ServiceError.PROMOTION_COUPON_HAS_RECEIVED); |
326 | } | 339 | } |
340 | + return redisLock; | ||
327 | 341 | ||
328 | } | 342 | } |
329 | 343 |
-
Please register or login to post a comment