Commit b3488624 by wuwenlong

下单防并发优化;

parent 681840e2
...@@ -24,6 +24,8 @@ public class Constants ...@@ -24,6 +24,8 @@ public class Constants
public static final String CONFIG_KEY_API_URL = "https://www.coujio.com"; //admin接口地址 public static final String CONFIG_KEY_API_URL = "https://www.coujio.com"; //admin接口地址
// 订单取消Key // 订单取消Key
public static final String ORDER_AUTO_CANCEL_KEY = "order_auto_cancel_key"; public static final String ORDER_AUTO_CANCEL_KEY = "order_auto_cancel_key";
// 订单锁定Key
public static final String ORDER_LOCK_KEY = "order_lock_key";
//测试环境,经测试需要,手机验证码测试环境可以不需要就能登录,value为1,则不验证验证码 //测试环境,经测试需要,手机验证码测试环境可以不需要就能登录,value为1,则不验证验证码
public static final String PHONE_TEST_KEY = "phone_test_key"; public static final String PHONE_TEST_KEY = "phone_test_key";
//通过uuid缓存的key 查找对应的 token数据 WX_TOKEN_USER:TOKEN //通过uuid缓存的key 查找对应的 token数据 WX_TOKEN_USER:TOKEN
......
...@@ -127,12 +127,10 @@ public class OrderTask { ...@@ -127,12 +127,10 @@ public class OrderTask {
String cancelStr; String cancelStr;
DateTime cancelTime; DateTime cancelTime;
cancelStr = sysConfigService.selectConfigByKey("order_cancel_time"); cancelStr = sysConfigService.selectConfigByKey("order_cancel_time");
if (StrUtil.isBlank(cancelStr)) { if (StrUtil.isBlank(cancelStr)) {
cancelStr = "1"; cancelStr = "5";
} }
cancelTime = cn.hutool.core.date.DateUtil.offset(sOrder.getCreateTime(), DateField.HOUR_OF_DAY, Integer.parseInt(cancelStr)); cancelTime = cn.hutool.core.date.DateUtil.offset(sOrder.getCreateTime(), DateField.MINUTE, Integer.parseInt(cancelStr));
long between = cn.hutool.core.date.DateUtil.between(cancelTime, cn.hutool.core.date.DateUtil.date(), DateUnit.SECOND, false); long between = cn.hutool.core.date.DateUtil.between(cancelTime, cn.hutool.core.date.DateUtil.date(), DateUnit.SECOND, false);
if (between < 0) {// 未到过期时间继续循环 if (between < 0) {// 未到过期时间继续循环
return Boolean.FALSE; return Boolean.FALSE;
...@@ -147,6 +145,7 @@ public class OrderTask { ...@@ -147,6 +145,7 @@ public class OrderTask {
couponUser.setUseStatus(CouponStatusEnum.NORMAL.getValue()); couponUser.setUseStatus(CouponStatusEnum.NORMAL.getValue());
consumerCouponService.updateById(couponUser); consumerCouponService.updateById(couponUser);
} }
logger.info(String.format("删除订单,订单号【%s】",sOrder.getOrderNo()));
return Boolean.TRUE; return Boolean.TRUE;
}); });
return execute; return execute;
......
...@@ -88,9 +88,6 @@ public class SOrderServiceImpl extends ServiceImpl<SOrderMapper, SOrder> impleme ...@@ -88,9 +88,6 @@ public class SOrderServiceImpl extends ServiceImpl<SOrderMapper, SOrder> impleme
private QPService qpService; private QPService qpService;
@Autowired @Autowired
private RedisUtil redisUtils;
@Autowired
private ISConsumptionRecordsService sConsumptionRecordsService; private ISConsumptionRecordsService sConsumptionRecordsService;
@Autowired @Autowired
...@@ -286,7 +283,7 @@ public class SOrderServiceImpl extends ServiceImpl<SOrderMapper, SOrder> impleme ...@@ -286,7 +283,7 @@ public class SOrderServiceImpl extends ServiceImpl<SOrderMapper, SOrder> impleme
queryWrapper.eq(SOrder::getRoomId, roomId); queryWrapper.eq(SOrder::getRoomId, roomId);
queryWrapper.notIn(SOrder::getRefundStatus, RefundStatusEnum.getRefundedStatus()); queryWrapper.notIn(SOrder::getRefundStatus, RefundStatusEnum.getRefundedStatus());
queryWrapper.in(SOrder::getStatus, OrderStatusEnum.getValidOrderStatus()); queryWrapper.in(SOrder::getStatus, OrderStatusEnum.getValidOrderStatus());
queryWrapper.eq(SOrder::getPayStatus, YesNoEnum.yes.getIndex()); queryWrapper.eq(SOrder::getIsDelete, YesNoEnum.no.getIndex());
String nowDayStr = DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD, day); String nowDayStr = DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD, day);
String nextDayStr = DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD, DateUtils.addDays(day, 1)); String nextDayStr = DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD, DateUtils.addDays(day, 1));
String yesterdayStr = DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD, DateUtils.addDays(day, -1)) + " 23"; String yesterdayStr = DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD, DateUtils.addDays(day, -1)) + " 23";
...@@ -302,6 +299,9 @@ public class SOrderServiceImpl extends ServiceImpl<SOrderMapper, SOrder> impleme ...@@ -302,6 +299,9 @@ public class SOrderServiceImpl extends ServiceImpl<SOrderMapper, SOrder> impleme
@Override @Override
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public OrderPayResultResponse createOrder(CreateOrderRequest request) { public OrderPayResultResponse createOrder(CreateOrderRequest request) {
String lockResult = "";
try {
lockResult = lockOrder(request);
SConsumer user = FrontTokenComponent.getWxSConsumerEntry(); SConsumer user = FrontTokenComponent.getWxSConsumerEntry();
if (ObjectUtil.isNull(user)) { if (ObjectUtil.isNull(user)) {
throw new BaseException("您的登录已过期,请先登录"); throw new BaseException("您的登录已过期,请先登录");
...@@ -364,7 +364,7 @@ public class SOrderServiceImpl extends ServiceImpl<SOrderMapper, SOrder> impleme ...@@ -364,7 +364,7 @@ public class SOrderServiceImpl extends ServiceImpl<SOrderMapper, SOrder> impleme
map.put("expirationTime", sOrder.getPreStartDate().toString()); map.put("expirationTime", sOrder.getPreStartDate().toString());
JSONObject jsonObject = new JSONObject(map); JSONObject jsonObject = new JSONObject(map);
if (sOrder.getOrderType().equals(OrderTypeEnum.RESERVER.getCode())) { if (sOrder.getOrderType().equals(OrderTypeEnum.RESERVER.getCode())) {
redisUtils.set(ReceiptRdeisEnum.ORDER_NO.getValue() + sOrder.getOrderNo(), jsonObject.toString()); redisUtil.set(ReceiptRdeisEnum.ORDER_NO.getValue() + sOrder.getOrderNo(), jsonObject.toString());
} }
} }
if (sOrder.getOrderType().equals(OrderTypeEnum.RENEW.getCode())) { if (sOrder.getOrderType().equals(OrderTypeEnum.RENEW.getCode())) {
...@@ -392,10 +392,38 @@ public class SOrderServiceImpl extends ServiceImpl<SOrderMapper, SOrder> impleme ...@@ -392,10 +392,38 @@ public class SOrderServiceImpl extends ServiceImpl<SOrderMapper, SOrder> impleme
map.put("orderNo", sOrder.getOrderNo()); map.put("orderNo", sOrder.getOrderNo());
map.put("expirationTime", sOrder.getEndDate().toString()); map.put("expirationTime", sOrder.getEndDate().toString());
JSONObject jsonObject = new JSONObject(map); JSONObject jsonObject = new JSONObject(map);
redisUtils.set(ReceiptRdeisEnum.ORDER_NO_KEY.getValue() + sOrder.getOrderNo(), jsonObject.toString()); redisUtil.set(ReceiptRdeisEnum.ORDER_NO_KEY.getValue() + sOrder.getOrderNo(), jsonObject.toString());
} }
return response; return response;
}catch (BaseException e){
throw e;
}finally {
unLockOrder(request,lockResult);
}
}
private String lockOrder(CreateOrderRequest request) throws BaseException {
try {
//自旋10次,每次等待1秒
String lockResult = "";
for (int i = 0; i < 10; i++) {
lockResult = redisUtil.lockWithTimeout(Constants.ORDER_LOCK_KEY + request.getRoomId(), 11, 1);
if (StringUtils.isBlank(lockResult)) {
Thread.sleep(1000L);
} else {
break;
}
}
return lockResult;
}catch (Exception e){
throw new BaseException("当前房间下单太火爆了,请稍后再试!");
}
}
private void unLockOrder(CreateOrderRequest request,String keyValue) {
if(StringUtils.isNotBlank(keyValue)) {
redisUtil.unLock(Constants.ORDER_LOCK_KEY + request.getRoomId(), keyValue, 1);
}
} }
private void checkOrderPack(CreateOrderRequest request, SConsumer user) { private void checkOrderPack(CreateOrderRequest request, SConsumer user) {
...@@ -438,7 +466,8 @@ public class SOrderServiceImpl extends ServiceImpl<SOrderMapper, SOrder> impleme ...@@ -438,7 +466,8 @@ public class SOrderServiceImpl extends ServiceImpl<SOrderMapper, SOrder> impleme
LambdaQueryWrapper<SOrder> queryWrapper = new LambdaQueryWrapper<>(); LambdaQueryWrapper<SOrder> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.notIn(SOrder::getRefundStatus, RefundStatusEnum.getRefundedStatus()); queryWrapper.notIn(SOrder::getRefundStatus, RefundStatusEnum.getRefundedStatus());
queryWrapper.in(SOrder::getStatus, OrderStatusEnum.getValidOrderStatus()); queryWrapper.in(SOrder::getStatus, OrderStatusEnum.getValidOrderStatus());
queryWrapper.eq(SOrder::getPayStatus, YesNoEnum.yes.getIndex()); // queryWrapper.eq(SOrder::getPayStatus, YesNoEnum.yes.getIndex());
queryWrapper.eq(SOrder::getIsDelete,YesNoEnum.no.getIndex());
queryWrapper.eq(SOrder::getStoreId, request.getStoreId()); queryWrapper.eq(SOrder::getStoreId, request.getStoreId());
queryWrapper.eq(SOrder::getRoomId, request.getRoomId()); queryWrapper.eq(SOrder::getRoomId, request.getRoomId());
switch (OrderTypeEnum.getEnumByCode(request.getOrderType())) { switch (OrderTypeEnum.getEnumByCode(request.getOrderType())) {
...@@ -737,14 +766,14 @@ public class SOrderServiceImpl extends ServiceImpl<SOrderMapper, SOrder> impleme ...@@ -737,14 +766,14 @@ public class SOrderServiceImpl extends ServiceImpl<SOrderMapper, SOrder> impleme
map.put("orderNo", sOrder.getOrderNo()); map.put("orderNo", sOrder.getOrderNo());
map.put("expirationTime", sOrder.getEndDate().toString()); map.put("expirationTime", sOrder.getEndDate().toString());
JSONObject jsonObject = new JSONObject(map); JSONObject jsonObject = new JSONObject(map);
redisUtils.set(ReceiptRdeisEnum.ORDER_NO_KEY.getValue() + sOrder.getOrderNo(), jsonObject.toString()); redisUtil.set(ReceiptRdeisEnum.ORDER_NO_KEY.getValue() + sOrder.getOrderNo(), jsonObject.toString());
} else if (sOrder.getOrderType().equals(OrderTypeEnum.RESERVER.getCode())) { } else if (sOrder.getOrderType().equals(OrderTypeEnum.RESERVER.getCode())) {
wechatNewService.sendMiniSubscribeMessage(sOrder, MessageReminderEnum.RESERVER); wechatNewService.sendMiniSubscribeMessage(sOrder, MessageReminderEnum.RESERVER);
Map<String, String> map = new HashMap<>(); Map<String, String> map = new HashMap<>();
map.put("orderNo", sOrder.getOrderNo()); map.put("orderNo", sOrder.getOrderNo());
map.put("expirationTime", sOrder.getPreStartDate().toString()); map.put("expirationTime", sOrder.getPreStartDate().toString());
JSONObject jsonObject = new JSONObject(map); JSONObject jsonObject = new JSONObject(map);
redisUtils.set(ReceiptRdeisEnum.ORDER_NO.getValue() + sOrder.getOrderNo(), jsonObject.toString()); redisUtil.set(ReceiptRdeisEnum.ORDER_NO.getValue() + sOrder.getOrderNo(), jsonObject.toString());
} }
baseMapper.updateById(sOrder); baseMapper.updateById(sOrder);
Long couponId = sOrder.getCouponId(); Long couponId = sOrder.getCouponId();
...@@ -823,7 +852,7 @@ public class SOrderServiceImpl extends ServiceImpl<SOrderMapper, SOrder> impleme ...@@ -823,7 +852,7 @@ public class SOrderServiceImpl extends ServiceImpl<SOrderMapper, SOrder> impleme
// 退款成功 // 退款成功
if (isRefund) { if (isRefund) {
// 删除redis 缓存信息,防止退款订单自动开始及给用户发送提示短信 // 删除redis 缓存信息,防止退款订单自动开始及给用户发送提示短信
redisUtils.delete(ReceiptRdeisEnum.ORDER_NO.getValue() + sOrder.getOrderNo()); redisUtil.delete(ReceiptRdeisEnum.ORDER_NO.getValue() + sOrder.getOrderNo());
//房间断电 //房间断电
deviceOpService.openOrCloseDevice(sOrder.getRoomId(), sOrder.getConsumerPhone(), OpTypeEnum.CUT_ELECTRIC.getCode(), true, 5); deviceOpService.openOrCloseDevice(sOrder.getRoomId(), sOrder.getConsumerPhone(), OpTypeEnum.CUT_ELECTRIC.getCode(), true, 5);
} }
...@@ -982,7 +1011,7 @@ public class SOrderServiceImpl extends ServiceImpl<SOrderMapper, SOrder> impleme ...@@ -982,7 +1011,7 @@ public class SOrderServiceImpl extends ServiceImpl<SOrderMapper, SOrder> impleme
map.put("orderNo", sOrder.getOrderNo()); map.put("orderNo", sOrder.getOrderNo());
map.put("expirationTime", sOrder.getEndDate().toString()); map.put("expirationTime", sOrder.getEndDate().toString());
JSONObject jsonObject = new JSONObject(map); JSONObject jsonObject = new JSONObject(map);
redisUtils.set(ReceiptRdeisEnum.ORDER_NO_KEY.getValue() + sOrder.getOrderNo(), jsonObject.toString()); redisUtil.set(ReceiptRdeisEnum.ORDER_NO_KEY.getValue() + sOrder.getOrderNo(), jsonObject.toString());
sOrder.setArrivalTime(new Date()); sOrder.setArrivalTime(new Date());
baseMapper.updateById(sOrder); baseMapper.updateById(sOrder);
//更改房间状态 //更改房间状态
...@@ -993,7 +1022,7 @@ public class SOrderServiceImpl extends ServiceImpl<SOrderMapper, SOrder> impleme ...@@ -993,7 +1022,7 @@ public class SOrderServiceImpl extends ServiceImpl<SOrderMapper, SOrder> impleme
Device device1 = new Device(); Device device1 = new Device();
device1.setRoomId(sOrder.getRoomId()); device1.setRoomId(sOrder.getRoomId());
device1.setDevType(DeviceType.DEVICE_0001.getCode()); device1.setDevType(DeviceType.DEVICE_0001.getCode());
redisUtils.delete(ReceiptRdeisEnum.ORDER_NO.getValue() + sOrder.getOrderNo()); redisUtil.delete(ReceiptRdeisEnum.ORDER_NO.getValue() + sOrder.getOrderNo());
//开门、取电 //开门、取电
deviceOpService.openDoor(sRoomVo.getId(), sOrder.getConsumerPhone()); deviceOpService.openDoor(sRoomVo.getId(), sOrder.getConsumerPhone());
//语音 //语音
......
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