Commit b3488624 by wuwenlong

下单防并发优化;

parent 681840e2
......@@ -24,6 +24,8 @@ public class Constants
public static final String CONFIG_KEY_API_URL = "https://www.coujio.com"; //admin接口地址
// 订单取消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,则不验证验证码
public static final String PHONE_TEST_KEY = "phone_test_key";
//通过uuid缓存的key 查找对应的 token数据 WX_TOKEN_USER:TOKEN
......
......@@ -127,12 +127,10 @@ public class OrderTask {
String cancelStr;
DateTime cancelTime;
cancelStr = sysConfigService.selectConfigByKey("order_cancel_time");
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);
if (between < 0) {// 未到过期时间继续循环
return Boolean.FALSE;
......@@ -147,6 +145,7 @@ public class OrderTask {
couponUser.setUseStatus(CouponStatusEnum.NORMAL.getValue());
consumerCouponService.updateById(couponUser);
}
logger.info(String.format("删除订单,订单号【%s】",sOrder.getOrderNo()));
return Boolean.TRUE;
});
return execute;
......
......@@ -88,9 +88,6 @@ public class SOrderServiceImpl extends ServiceImpl<SOrderMapper, SOrder> impleme
private QPService qpService;
@Autowired
private RedisUtil redisUtils;
@Autowired
private ISConsumptionRecordsService sConsumptionRecordsService;
@Autowired
......@@ -286,7 +283,7 @@ public class SOrderServiceImpl extends ServiceImpl<SOrderMapper, SOrder> impleme
queryWrapper.eq(SOrder::getRoomId, roomId);
queryWrapper.notIn(SOrder::getRefundStatus, RefundStatusEnum.getRefundedStatus());
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 nextDayStr = DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD, DateUtils.addDays(day, 1));
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
@Override
@Transactional(rollbackFor = Exception.class)
public OrderPayResultResponse createOrder(CreateOrderRequest request) {
String lockResult = "";
try {
lockResult = lockOrder(request);
SConsumer user = FrontTokenComponent.getWxSConsumerEntry();
if (ObjectUtil.isNull(user)) {
throw new BaseException("您的登录已过期,请先登录");
......@@ -364,7 +364,7 @@ public class SOrderServiceImpl extends ServiceImpl<SOrderMapper, SOrder> impleme
map.put("expirationTime", sOrder.getPreStartDate().toString());
JSONObject jsonObject = new JSONObject(map);
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())) {
......@@ -392,10 +392,38 @@ public class SOrderServiceImpl extends ServiceImpl<SOrderMapper, SOrder> impleme
map.put("orderNo", sOrder.getOrderNo());
map.put("expirationTime", sOrder.getEndDate().toString());
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;
}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) {
......@@ -438,7 +466,8 @@ public class SOrderServiceImpl extends ServiceImpl<SOrderMapper, SOrder> impleme
LambdaQueryWrapper<SOrder> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.notIn(SOrder::getRefundStatus, RefundStatusEnum.getRefundedStatus());
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::getRoomId, request.getRoomId());
switch (OrderTypeEnum.getEnumByCode(request.getOrderType())) {
......@@ -737,14 +766,14 @@ public class SOrderServiceImpl extends ServiceImpl<SOrderMapper, SOrder> impleme
map.put("orderNo", sOrder.getOrderNo());
map.put("expirationTime", sOrder.getEndDate().toString());
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())) {
wechatNewService.sendMiniSubscribeMessage(sOrder, MessageReminderEnum.RESERVER);
Map<String, String> map = new HashMap<>();
map.put("orderNo", sOrder.getOrderNo());
map.put("expirationTime", sOrder.getPreStartDate().toString());
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);
Long couponId = sOrder.getCouponId();
......@@ -823,7 +852,7 @@ public class SOrderServiceImpl extends ServiceImpl<SOrderMapper, SOrder> impleme
// 退款成功
if (isRefund) {
// 删除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);
}
......@@ -982,7 +1011,7 @@ public class SOrderServiceImpl extends ServiceImpl<SOrderMapper, SOrder> impleme
map.put("orderNo", sOrder.getOrderNo());
map.put("expirationTime", sOrder.getEndDate().toString());
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());
baseMapper.updateById(sOrder);
//更改房间状态
......@@ -993,7 +1022,7 @@ public class SOrderServiceImpl extends ServiceImpl<SOrderMapper, SOrder> impleme
Device device1 = new Device();
device1.setRoomId(sOrder.getRoomId());
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());
//语音
......
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