Merge branch 'hotfix-20191028' into test6.9.14
# Conflicts: # promotion/src/main/java/com/yohoufo/promotion/service/impl/CouponServiceImpl.java
Showing
1 changed file
with
23 additions
and
8 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 | ||
@@ -202,6 +210,7 @@ public class CouponServiceImpl implements ICouponService { | @@ -202,6 +210,7 @@ public class CouponServiceImpl implements ICouponService { | ||
202 | logger.warn("sendCoupon query coupon info,coupontype is null:{}", couponToken); | 210 | logger.warn("sendCoupon query coupon info,coupontype is null:{}", couponToken); |
203 | throw new ServiceException(ServiceError.PROMOTION_COUPON_HAS_NOT_EXISTS); | 211 | throw new ServiceException(ServiceError.PROMOTION_COUPON_HAS_NOT_EXISTS); |
204 | } | 212 | } |
213 | + | ||
205 | Coupon coupon = couponAndType.getCoupon(); | 214 | Coupon coupon = couponAndType.getCoupon(); |
206 | //check receive start time | 215 | //check receive start time |
207 | if(receiveStartTimeChkNecessary){ | 216 | if(receiveStartTimeChkNecessary){ |
@@ -211,7 +220,7 @@ public class CouponServiceImpl implements ICouponService { | @@ -211,7 +220,7 @@ public class CouponServiceImpl implements ICouponService { | ||
211 | 220 | ||
212 | if(!repeatable){ | 221 | if(!repeatable){ |
213 | // 校验是否可以领取(重复领取,时间是否合法,状态) | 222 | // 校验是否可以领取(重复领取,时间是否合法,状态) |
214 | - checkCanAcquire(uid, couponToken, couponAndType); | 223 | + redisLock = checkCanAcquire(uid, couponToken, couponAndType); |
215 | } | 224 | } |
216 | 225 | ||
217 | if (coupon.getStatus() != CouponsStatusEnum.VALID.getCode()){ | 226 | if (coupon.getStatus() != CouponsStatusEnum.VALID.getCode()){ |
@@ -235,19 +244,16 @@ public class CouponServiceImpl implements ICouponService { | @@ -235,19 +244,16 @@ public class CouponServiceImpl implements ICouponService { | ||
235 | } | 244 | } |
236 | 245 | ||
237 | int count = 0; | 246 | int count = 0; |
238 | - // 不可重复 | ||
239 | - if (!repeatable){ | ||
240 | - count = userCouponMapper.insertWhere(userCoupon); | ||
241 | - }else{ | ||
242 | count = userCouponMapper.insert(userCoupon); | 247 | count = userCouponMapper.insert(userCoupon); |
243 | - } | ||
244 | - | ||
245 | if (count == 0){ | 248 | if (count == 0){ |
246 | logger.info("can not repeatable acquire coupon. uid is {}, coupon is {}", uid, couponToken); | 249 | logger.info("can not repeatable acquire coupon. uid is {}, coupon is {}", uid, couponToken); |
247 | throw new ServiceException(ServiceError.PROMOTION_COUPON_HAS_RECEIVED); | 250 | throw new ServiceException(ServiceError.PROMOTION_COUPON_HAS_RECEIVED); |
248 | } | 251 | } |
249 | 252 | ||
250 | logger.info("senCoupon success,{},{},{},{}", uid, couponToken, couponCode, count); | 253 | logger.info("senCoupon success,{},{},{},{}", uid, couponToken, couponCode, count); |
254 | + if(Objects.nonNull(redisLock)){ | ||
255 | + redisLock.unlock(); | ||
256 | + } | ||
251 | return couponCode; | 257 | return couponCode; |
252 | } | 258 | } |
253 | 259 | ||
@@ -344,13 +350,22 @@ public class CouponServiceImpl implements ICouponService { | @@ -344,13 +350,22 @@ public class CouponServiceImpl implements ICouponService { | ||
344 | } | 350 | } |
345 | 351 | ||
346 | 352 | ||
347 | - private void checkCanAcquire(Integer uid, String couponToken, CouponAndType couponAndType) { | 353 | + private RedisLock checkCanAcquire(Integer uid, String couponToken, CouponAndType couponAndType) { |
348 | // 验证该用户是否重复领取 | 354 | // 验证该用户是否重复领取 |
349 | UserCoupon userCoupon = userCouponMapper.selectByUidAndToken(uid, couponToken); | 355 | UserCoupon userCoupon = userCouponMapper.selectByUidAndToken(uid, couponToken); |
356 | + | ||
357 | + RedisLock redisLock = redisLockFactory.newLock(RedisKeyBuilder.newInstance() | ||
358 | + .appendFixed("ufo:promotion:coupons:checkCanAcquire:") | ||
359 | + .appendVar(uid + "-" + couponToken), 3, TimeUnit.SECONDS); | ||
360 | + if (!redisLock.tryLock()) { | ||
361 | + logger.info("{} checkCanAcquire fail, it already in the process", uid); | ||
362 | + throw new UfoServiceException(400, "优惠券领取中"); | ||
363 | + } | ||
350 | if (userCoupon != null){ | 364 | if (userCoupon != null){ |
351 | logger.warn("user has acquried this coupon before:{},{}", uid, couponToken); | 365 | logger.warn("user has acquried this coupon before:{},{}", uid, couponToken); |
352 | throw new ServiceException(ServiceError.PROMOTION_COUPON_HAS_RECEIVED); | 366 | throw new ServiceException(ServiceError.PROMOTION_COUPON_HAS_RECEIVED); |
353 | } | 367 | } |
368 | + return redisLock; | ||
354 | 369 | ||
355 | } | 370 | } |
356 | 371 |
-
Please register or login to post a comment