use of com.whoiszxl.entity.SeckillItem in project shopzz by whoiszxl.
the class SeckillItemAdminController method save.
@SaCheckLogin
@PostMapping
@ApiOperation(value = "新增秒杀商品", notes = "新增秒杀商品", response = ResponseResult.class)
public ResponseResult<Boolean> save(@RequestBody SeckillItemSaveCommand bannerSaveCommand) {
SeckillItem seckillItem = dozerUtils.map(bannerSaveCommand, SeckillItem.class);
boolean saveFlag = seckillItemService.save(seckillItem);
return ResponseResult.buildByFlag(saveFlag);
}
use of com.whoiszxl.entity.SeckillItem in project shopzz by whoiszxl.
the class DefaultStockCacheServiceImpl method initItemStock.
@Override
public boolean initItemStock(Long seckillItemId) {
try {
SeckillItem seckillItem = seckillItemService.getById(seckillItemId);
if (seckillItem == null) {
log.info("秒杀商品不存在, id:{}", seckillItemId);
return false;
}
if (seckillItem.getInitStockQuantity() < 1) {
log.info("秒杀商品库存未配置, id:{}", seckillItemId);
return false;
}
// 构建lua脚本
DefaultRedisScript<Long> redisScript = new DefaultRedisScript<>(INIT_STOCK_LUA, Long.class);
String stockCacheKey = RedisKeyPrefixConstants.CACHE_ITEM_STOCK + seckillItemId;
String stockCacheAlignKey = RedisKeyPrefixConstants.CACHE_ITEM_STOCK_ALIGN + seckillItemId;
List<String> keys = Lists.newArrayList(stockCacheKey, stockCacheAlignKey);
Long result = (Long) redisUtils.execute(redisScript, keys, seckillItem.getInitStockQuantity().toString());
if (result == null) {
log.info("库存初始化失败,id:{}", seckillItemId);
return false;
}
if (result == -997) {
log.info("库存正在初始化中,本次初始化取消,id:{}", seckillItemId);
return true;
}
if (result == 1) {
log.info("库存初始化完成, id:{}", seckillItemId);
return true;
}
return false;
} catch (Exception e) {
log.error("初始化库存发生异常:{}", e);
return false;
}
}
use of com.whoiszxl.entity.SeckillItem in project shopzz by whoiszxl.
the class QueuedPlaceOrderServiceImpl method handlePlaceOrderTask.
@Override
@Transactional
public void handlePlaceOrderTask(SeckillPlaceOrderDTO seckillPlaceOrderDTO) {
try {
// 再次校验秒杀活动与秒杀商品的有效性
boolean allowFlag = checkSeckill(seckillPlaceOrderDTO.getSeckillId());
AssertUtils.isTrue(allowFlag, "秒杀活动校验失败");
allowFlag = checkSeckillItem(seckillPlaceOrderDTO.getSeckillItemId());
AssertUtils.isTrue(allowFlag, "秒杀商品校验失败");
// 缓存中获取秒杀item,并将缓存中的库存设置上
SeckillItem seckillItem = seckillItemService.getById(seckillPlaceOrderDTO.getSeckillItemId());
// 进行库存实际扣减,因为通过token已经拦截了一次,可以直接进行数据库扣减,而不用走缓存扣减一次了
boolean subDbFlag = seckillItemService.subDbStock(seckillPlaceOrderDTO.getSeckillItemId(), seckillPlaceOrderDTO.getQuantity());
AssertUtils.isTrue(subDbFlag, "库存扣减失败");
// 订单持久化
SeckillOrder seckillOrder = buildSeckillOrder(seckillItem, seckillPlaceOrderDTO, seckillPlaceOrderDTO.getMemberId());
boolean saveFlag = seckillOrderService.save(seckillOrder);
if (!saveFlag) {
ExceptionCatcher.catchValidateEx(ResponseResult.buildError("下单失败"));
}
// 如果taskKey的值为0,则说明还没执行完成,则设置为1
Object taskValueObj = redisUtils.getObj(RedisKeyPrefixConstants.TASK_SECKILL_PLACE_ORDER_MQ + seckillPlaceOrderDTO.getTaskKey());
if ("0".equals(taskValueObj)) {
redisUtils.set(RedisKeyPrefixConstants.TASK_SECKILL_PLACE_ORDER_MQ + seckillPlaceOrderDTO.getTaskKey(), "1");
}
// 将订单ID设置到Redis中
redisUtils.setEx(RedisKeyPrefixConstants.TASK_SECKILL_PLACE_ORDER_MQ_ORDER_ID + seckillPlaceOrderDTO.getTaskKey(), seckillOrder.getId().toString(), 24, TimeUnit.HOURS);
log.info("handlePlaceOrderTask|MQ消费秒杀订单任务处理完成|{}", seckillPlaceOrderDTO);
} catch (Exception e) {
// 发生异常,设置为-1
Object taskValueObj = redisUtils.getObj(RedisKeyPrefixConstants.TASK_SECKILL_PLACE_ORDER_MQ + seckillPlaceOrderDTO.getTaskKey());
if (taskValueObj != null && "0".equals(taskValueObj)) {
redisUtils.set(RedisKeyPrefixConstants.TASK_SECKILL_PLACE_ORDER_MQ + seckillPlaceOrderDTO.getTaskKey(), "-1");
}
log.info("handlePlaceOrderTask|MQ消费秒杀订单任务处理发生异常|{}", seckillPlaceOrderDTO, e);
ExceptionCatcher.catchValidateEx(ResponseResult.buildError("下单失败"));
}
}
use of com.whoiszxl.entity.SeckillItem in project shopzz by whoiszxl.
the class DefaultPlaceOrderServiceImpl method doPlaceOrder.
@Override
public Long doPlaceOrder(Long memberId, SeckillOrderSubmitCommand seckillOrderSubmitCommand) {
boolean allowFlag = checkSeckill(seckillOrderSubmitCommand.getSeckillId());
AssertUtils.isTrue(allowFlag, "秒杀活动校验失败");
allowFlag = checkSeckillItem(seckillOrderSubmitCommand.getSeckillItemId());
AssertUtils.isTrue(allowFlag, "秒杀商品校验失败");
// 缓存中获取秒杀item,并将缓存中的库存设置上
SeckillItemCache seckillItemCache = seckillItemCachedService.getCachedSeckillItem(seckillOrderSubmitCommand.getSeckillItemId(), null);
putStockToItem(seckillItemCache.getSeckillItem());
SeckillItem seckillItem = seckillItemCache.getSeckillItem();
boolean preSubCacheFlag = false;
try {
// 进行库存预扣减
preSubCacheFlag = stockCacheService.subCacheStock(seckillOrderSubmitCommand.getSeckillItemId(), seckillOrderSubmitCommand.getQuantity());
AssertUtils.isTrue(preSubCacheFlag, "库存预扣减失败");
// 进行库存实际扣减
boolean subDbFlag = seckillItemService.subDbStock(seckillOrderSubmitCommand.getSeckillItemId(), seckillOrderSubmitCommand.getQuantity());
AssertUtils.isTrue(subDbFlag, "库存扣减失败");
// 持久化订单
SeckillOrder seckillOrder = buildSeckillOrder(seckillItem, seckillOrderSubmitCommand);
boolean saveFlag = seckillOrderService.save(seckillOrder);
if (!saveFlag) {
ExceptionCatcher.catchValidateEx(ResponseResult.buildError("下单失败"));
}
return seckillOrder.getId();
} catch (Exception e) {
// 如果预下单成功了,回滚缓存里的库存数量
if (preSubCacheFlag) {
boolean recoverFlag = stockCacheService.addCacheStock(seckillOrderSubmitCommand.getSeckillItemId(), seckillOrderSubmitCommand.getQuantity());
if (!recoverFlag) {
log.error("预扣减库存恢复失败,用户ID:{}, 秒杀商品ID:{}, 秒杀数量:{}", memberId, seckillOrderSubmitCommand.getSeckillItemId(), seckillOrderSubmitCommand.getQuantity());
}
ExceptionCatcher.catchValidateEx(ResponseResult.buildError("下单失败"));
}
}
return null;
}
use of com.whoiszxl.entity.SeckillItem in project shopzz by whoiszxl.
the class SeckillItemCachedServiceImpl method loadDb.
private SeckillItemCache loadDb(Long seckillItemId) {
DistributedLock lock = distributedLockFactory.getDistributedLock(RedisKeyPrefixConstants.LOCK_GET_ITEM_FROM_DB + seckillItemId);
try {
boolean isLockSuccess = lock.tryLock(1, 5, TimeUnit.SECONDS);
if (!isLockSuccess) {
return new SeckillItemCache().tryLater();
}
SeckillItem seckillItem = seckillItemService.getById(seckillItemId);
SeckillItemCache seckillItemCache;
if (seckillItem == null) {
seckillItemCache = new SeckillItemCache().notExist();
} else {
seckillItemCache = new SeckillItemCache().with(seckillItem);
}
redisUtils.setEx(RedisKeyPrefixConstants.CACHE_SECKILL_ITEM + seckillItemId, JsonUtil.toJson(seckillItemCache), 3, TimeUnit.SECONDS);
log.info("从数据库加载数据,并保存到redis中:{}", seckillItemCache);
return seckillItemCache;
} catch (Exception e) {
log.error("从数据库加载数据失败", e);
return new SeckillItemCache().tryLater();
} finally {
lock.unlock();
}
}
Aggregations