Search in sources :

Example 1 with DistributedLock

use of com.actionworks.flashsale.lock.DistributedLock in project flash-sale by ThoughtsBeta.

the class RedissonLockService method getDistributedLock.

@Override
public DistributedLock getDistributedLock(String key) {
    RLock rLock = redissonClient.getLock(key);
    return new DistributedLock() {

        @Override
        public boolean tryLock(long waitTime, long leaseTime, TimeUnit unit) throws InterruptedException {
            boolean isLockSuccess = rLock.tryLock(waitTime, leaseTime, unit);
            logger.info("{} get lock result:{}", key, isLockSuccess);
            return isLockSuccess;
        }

        @Override
        public void lock(long leaseTime, TimeUnit unit) {
            rLock.lock(leaseTime, unit);
        }

        @Override
        public void unlock() {
            if (isLocked() && isHeldByCurrentThread()) {
                rLock.unlock();
            }
        }

        @Override
        public boolean isLocked() {
            return rLock.isLocked();
        }

        @Override
        public boolean isHeldByThread(long threadId) {
            return rLock.isHeldByThread(threadId);
        }

        @Override
        public boolean isHeldByCurrentThread() {
            return rLock.isHeldByCurrentThread();
        }
    };
}
Also used : DistributedLock(com.actionworks.flashsale.lock.DistributedLock) TimeUnit(java.util.concurrent.TimeUnit) RLock(org.redisson.api.RLock)

Example 2 with DistributedLock

use of com.actionworks.flashsale.lock.DistributedLock in project flash-sale by ThoughtsBeta.

the class FlashItemCacheService method tryToUpdateItemCacheByLock.

public FlashItemCache tryToUpdateItemCacheByLock(Long itemId) {
    logger.info("itemCache|更新远程缓存|{}", itemId);
    DistributedLock lock = distributedLockFactoryService.getDistributedLock(UPDATE_ITEM_CACHE_LOCK_KEY + itemId);
    try {
        boolean isLockSuccess = lock.tryLock(1, 5, TimeUnit.SECONDS);
        if (!isLockSuccess) {
            return new FlashItemCache().tryLater();
        }
        FlashItem flashItem = flashItemDomainService.getFlashItem(itemId);
        FlashItemCache flashItemCache;
        if (flashItem == null) {
            flashItemCache = new FlashItemCache().notExist();
        } else {
            flashItemCache = new FlashItemCache().with(flashItem).withVersion(System.currentTimeMillis());
        }
        distributedCacheService.put(buildItemCacheKey(itemId), JSON.toJSONString(flashItemCache), FIVE_MINUTES);
        logger.info("itemCache|远程缓存已更新|{}", itemId);
        return flashItemCache;
    } catch (InterruptedException e) {
        logger.error("itemCache|远程缓存更新失败|{}", itemId);
        return new FlashItemCache().tryLater();
    } finally {
        lock.unlock();
    }
}
Also used : DistributedLock(com.actionworks.flashsale.lock.DistributedLock) FlashItemCache(com.actionworks.flashsale.app.service.item.cache.model.FlashItemCache) FlashItem(com.actionworks.flashsale.domain.model.entity.FlashItem)

Example 3 with DistributedLock

use of com.actionworks.flashsale.lock.DistributedLock in project flash-sale by ThoughtsBeta.

the class FlashItemsCacheService method tryToUpdateItemsCacheByLock.

public FlashItemsCache tryToUpdateItemsCacheByLock(Long activityId) {
    logger.info("itemsCache|更新远程缓存|{}", activityId);
    DistributedLock lock = distributedLockFactoryService.getDistributedLock(UPDATE_ITEMS_CACHE_LOCK_KEY + activityId);
    try {
        boolean isLockSuccess = lock.tryLock(1, 5, TimeUnit.SECONDS);
        if (!isLockSuccess) {
            return new FlashItemsCache().tryLater();
        }
        PagesQueryCondition pagesQueryCondition = new PagesQueryCondition();
        pagesQueryCondition.setActivityId(activityId);
        pagesQueryCondition.setStatus(FlashItemStatus.ONLINE.getCode());
        PageResult<FlashItem> flashItemPageResult = flashItemDomainService.getFlashItems(pagesQueryCondition);
        FlashItemsCache flashItemsCache;
        if (flashItemPageResult == null) {
            flashItemsCache = new FlashItemsCache().notExist();
        } else {
            flashItemsCache = new FlashItemsCache().setTotal(flashItemPageResult.getTotal()).setFlashItems(flashItemPageResult.getData()).setVersion(System.currentTimeMillis());
        }
        distributedCacheService.put(buildItemCacheKey(activityId), JSON.toJSONString(flashItemsCache), FIVE_MINUTES);
        logger.info("itemsCache|远程缓存已更新|{}", activityId);
        return flashItemsCache;
    } catch (Exception e) {
        logger.error("itemsCache|远程缓存更新失败|{}", activityId);
        return new FlashItemsCache().tryLater();
    } finally {
        lock.unlock();
    }
}
Also used : DistributedLock(com.actionworks.flashsale.lock.DistributedLock) FlashItem(com.actionworks.flashsale.domain.model.entity.FlashItem) FlashItemsCache(com.actionworks.flashsale.app.service.item.cache.model.FlashItemsCache) PagesQueryCondition(com.actionworks.flashsale.domain.model.PagesQueryCondition)

Example 4 with DistributedLock

use of com.actionworks.flashsale.lock.DistributedLock in project flash-sale by ThoughtsBeta.

the class DefaultFlashOrderAppService method placeOrder.

@Override
@Transactional
public AppSimpleResult<PlaceOrderResult> placeOrder(Long userId, FlashPlaceOrderCommand placeOrderCommand) {
    logger.info("placeOrder|下单|{},{}", userId, JSON.toJSONString(placeOrderCommand));
    if (userId == null || placeOrderCommand == null || !placeOrderCommand.validateParams()) {
        throw new BizException(INVALID_PARAMS);
    }
    String placeOrderLockKey = getPlaceOrderLockKey(userId);
    DistributedLock placeOrderLock = lockFactoryService.getDistributedLock(placeOrderLockKey);
    try {
        boolean isLockSuccess = placeOrderLock.tryLock(5, 5, TimeUnit.SECONDS);
        if (!isLockSuccess) {
            return AppSimpleResult.failed(FREQUENTLY_ERROR.getErrCode(), FREQUENTLY_ERROR.getErrDesc());
        }
        boolean isPassRiskInspect = securityService.inspectRisksByPolicy(userId);
        if (!isPassRiskInspect) {
            logger.info("placeOrder|综合风控检验未通过|{}", userId);
            return AppSimpleResult.failed(PLACE_ORDER_FAILED);
        }
        PlaceOrderResult placeOrderResult = placeOrderService.doPlaceOrder(userId, placeOrderCommand);
        if (!placeOrderResult.isSuccess()) {
            return AppSimpleResult.failed(placeOrderResult.getCode(), placeOrderResult.getMessage());
        }
        logger.info("placeOrder|下单完成|{}", userId);
        return AppSimpleResult.ok(placeOrderResult);
    } catch (Exception e) {
        logger.error("placeOrder|下单失败|{},{}", userId, JSON.toJSONString(placeOrderCommand), e);
        return AppSimpleResult.failed(PLACE_ORDER_FAILED);
    } finally {
        placeOrderLock.unlock();
    }
}
Also used : PlaceOrderResult(com.actionworks.flashsale.app.model.result.PlaceOrderResult) DistributedLock(com.actionworks.flashsale.lock.DistributedLock) BizException(com.actionworks.flashsale.app.exception.BizException) BizException(com.actionworks.flashsale.app.exception.BizException) Transactional(org.springframework.transaction.annotation.Transactional)

Example 5 with DistributedLock

use of com.actionworks.flashsale.lock.DistributedLock in project flash-sale by ThoughtsBeta.

the class BucketsCacheService method alignItemStocks.

@Override
public boolean alignItemStocks(Long itemId) {
    if (itemId == null) {
        logger.info("alignItemStocks|参数为空");
        return false;
    }
    String stockBucketCacheInitLockKey = getStockBucketCacheInitLockKey(itemId);
    DistributedLock lock = distributedLockFactoryService.getDistributedLock(stockBucketCacheInitLockKey);
    try {
        boolean isLockSuccess = lock.tryLock(5, 5, TimeUnit.SECONDS);
        if (!isLockSuccess) {
            logger.info("alignItemStocks|校准库存时获取锁失败|{}", itemId);
            return false;
        }
        List<Bucket> buckets = bucketsDomainService.getBucketsByItem(itemId);
        if (CollectionUtils.isEmpty(buckets)) {
            logger.info("alignItemStocks|秒杀品未设置库存|{}", itemId);
            return false;
        }
        buckets.forEach(stockBucket -> {
            String key1StockBucketCacheKey = getBucketAvailableStocksCacheKey(stockBucket.getItemId(), stockBucket.getSerialNo());
            String key2StockBucketsSuspendKey = getItemStockBucketsSuspendKey(stockBucket.getItemId());
            String key3ItemStocksCacheAlignKey = getItemStocksCacheAlignKey(stockBucket.getItemId());
            String key4ItemStockBucketsQuantityCacheKey = getItemStockBucketsQuantityCacheKey(stockBucket.getItemId());
            List<String> keys = Lists.newArrayList(key1StockBucketCacheKey, key2StockBucketsSuspendKey, key3ItemStocksCacheAlignKey, key4ItemStockBucketsQuantityCacheKey);
            DefaultRedisScript<Long> redisScript = new DefaultRedisScript<>(INIT_OR_ALIGN_ITEM_STOCK_LUA, Long.class);
            Long result = redisCacheService.getRedisTemplate().execute(redisScript, keys, stockBucket.getAvailableStocksAmount(), buckets.size());
            if (result == null) {
                logger.info("alignItemStocks|分桶库存校准失败|{},{}", itemId, stockBucketCacheInitLockKey);
                return;
            }
            if (result == -998) {
                logger.info("alignItemStocks|库存维护中,已暂停服务|{},{},{}", result, itemId, stockBucketCacheInitLockKey);
                return;
            }
            if (result == -997) {
                logger.info("alignItemStocks|库存数据校准对齐中|{},{},{}", result, itemId, stockBucketCacheInitLockKey);
                return;
            }
            if (result == 1) {
                logger.info("alignItemStocks|分桶库存校准完成|{},{},{}", result, itemId, stockBucketCacheInitLockKey);
            }
        });
        logger.info("alignItemStocks|分桶库存校准全部完成|{},{}", itemId, stockBucketCacheInitLockKey);
        return true;
    } catch (Exception e) {
        logger.error("alignItemStocks|秒杀品库存初始化错误|{},{}", itemId, stockBucketCacheInitLockKey, e);
        return false;
    }
}
Also used : DistributedLock(com.actionworks.flashsale.lock.DistributedLock) Bucket(com.actionworks.flashsale.domain.model.Bucket) DefaultRedisScript(org.springframework.data.redis.core.script.DefaultRedisScript)

Aggregations

DistributedLock (com.actionworks.flashsale.lock.DistributedLock)17 BizException (com.actionworks.flashsale.app.exception.BizException)9 AuthResult (com.actionworks.flashsale.app.auth.model.AuthResult)7 AuthException (com.actionworks.flashsale.controller.exception.AuthException)7 FlashActivity (com.actionworks.flashsale.domain.model.entity.FlashActivity)4 FlashItem (com.actionworks.flashsale.domain.model.entity.FlashItem)4 Bucket (com.actionworks.flashsale.domain.model.Bucket)2 PagesQueryCondition (com.actionworks.flashsale.domain.model.PagesQueryCondition)2 Transactional (org.springframework.transaction.annotation.Transactional)2 AppException (com.actionworks.flashsale.app.exception.AppException)1 StockBucketException (com.actionworks.flashsale.app.exception.StockBucketException)1 PlaceOrderResult (com.actionworks.flashsale.app.model.result.PlaceOrderResult)1 FlashActivitiesCache (com.actionworks.flashsale.app.service.activity.cache.model.FlashActivitiesCache)1 FlashActivityCache (com.actionworks.flashsale.app.service.activity.cache.model.FlashActivityCache)1 FlashItemCache (com.actionworks.flashsale.app.service.item.cache.model.FlashItemCache)1 FlashItemsCache (com.actionworks.flashsale.app.service.item.cache.model.FlashItemsCache)1 ItemStockCache (com.actionworks.flashsale.app.service.stock.model.ItemStockCache)1 TimeUnit (java.util.concurrent.TimeUnit)1 RLock (org.redisson.api.RLock)1 DefaultRedisScript (org.springframework.data.redis.core.script.DefaultRedisScript)1