Search in sources :

Example 1 with DistributedLock

use of com.whoiszxl.DistributedLock 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();
    }
}
Also used : SeckillItem(com.whoiszxl.entity.SeckillItem) DistributedLock(com.whoiszxl.DistributedLock) SeckillItemCache(com.whoiszxl.cqrs.cache.SeckillItemCache)

Example 2 with DistributedLock

use of com.whoiszxl.DistributedLock in project shopzz by whoiszxl.

the class SeckillCachedServiceImpl method loadDb.

private SeckillCache loadDb(Long seckillId) {
    DistributedLock lock = distributedLockFactory.getDistributedLock(RedisKeyPrefixConstants.LOCK_GET_SECKILL_FROM_DB + seckillId);
    try {
        boolean isLockSuccess = lock.tryLock(1, 5, TimeUnit.SECONDS);
        if (!isLockSuccess) {
            return new SeckillCache().tryLater();
        }
        Seckill seckill = seckillService.getById(seckillId);
        SeckillCache seckillCache;
        if (seckill == null) {
            seckillCache = new SeckillCache().notExist();
        } else {
            seckillCache = new SeckillCache().with(seckill);
        }
        redisUtils.setEx(RedisKeyPrefixConstants.CACHE_SECKILL + seckillId, JsonUtil.toJson(seckillCache), 3, TimeUnit.MINUTES);
        log.info("从数据库加载数据,并保存到redis中:{}", seckillCache);
        return seckillCache;
    } catch (Exception e) {
        log.error("从数据库加载数据失败", e);
        return new SeckillCache().tryLater();
    } finally {
        lock.unlock();
    }
}
Also used : DistributedLock(com.whoiszxl.DistributedLock) SeckillCache(com.whoiszxl.cqrs.cache.SeckillCache) Seckill(com.whoiszxl.entity.Seckill)

Example 3 with DistributedLock

use of com.whoiszxl.DistributedLock in project shopzz by whoiszxl.

the class SeckillServiceImpl method orderSubmit.

@Override
@Transactional
public Long orderSubmit(SeckillOrderSubmitCommand seckillOrderSubmitCommand) {
    // 0. 获取当前登录用户
    Long memberId = AuthUtils.getMemberId();
    // 1. 获取用户分布式锁
    String lockKey = RedisKeyPrefixConstants.SECKILL_LOCK_ORDER_SUBMIT + memberId;
    DistributedLock lock = distributedLockFactory.getDistributedLock(lockKey);
    try {
        // 2. 尝试进行加锁,等待3秒,加锁成功后5秒释放
        boolean isLockSuccess = lock.tryLock(3, 5, TimeUnit.SECONDS);
        AssertUtils.isTrue(isLockSuccess, "加锁失败");
        // 3. 对用户进行风控检查
        boolean checkFlag = securityService.inspectRisk(memberId);
        AssertUtils.isTrue(checkFlag, "风控检测未通过");
        // 4. 下单
        Long orderId = placeOrderService.doPlaceOrder(memberId, seckillOrderSubmitCommand);
        AssertUtils.isNotNull(orderId, "下单失败");
        return orderId;
    } catch (InterruptedException e) {
        ExceptionCatcher.catchValidateEx(ResponseResult.buildError("加锁失败"));
        return null;
    } finally {
        lock.unlock();
    }
}
Also used : DistributedLock(com.whoiszxl.DistributedLock) Transactional(org.springframework.transaction.annotation.Transactional)

Example 4 with DistributedLock

use of com.whoiszxl.DistributedLock in project shopzz by whoiszxl.

the class QueuedPlaceOrderServiceImpl method refreshLatestAvailableToken.

/**
 * 从库存里获取可用token数量
 * token数量默认是库存的1.5倍,适量放行一些请求进来争抢资源
 * @param seckillItemId
 * @return
 */
private Integer refreshLatestAvailableToken(Long seckillItemId) {
    DistributedLock distributedLock = distributedLockFactory.getDistributedLock(RedisKeyPrefixConstants.LOCK_SECKILL_REFRESH_PLACE_ORDER_TOKEN + seckillItemId);
    try {
        boolean lockFlag = distributedLock.tryLock(500, 1000, TimeUnit.MILLISECONDS);
        if (!lockFlag) {
            return null;
        }
        StockCache stockCache = stockCacheService.getAvailableStock(seckillItemId);
        if (stockCache != null && stockCache.isSuccess() && stockCache.getAvailableStockQuantity() != null) {
            Integer latestAvailableOrderToken = (int) Math.ceil(stockCache.getAvailableStockQuantity() * 1.5);
            redisUtils.setEx(RedisKeyPrefixConstants.TOKEN_SECKILL_PLACE_ORDER + seckillItemId, latestAvailableOrderToken.toString(), 24, TimeUnit.HOURS);
            availableOrderTokenLocalCache.put(seckillItemId, latestAvailableOrderToken);
            return latestAvailableOrderToken;
        }
    } catch (Exception e) {
        log.error("refreshLatestAvailableToken|刷新最新可用令牌失败|{}", seckillItemId, e);
    } finally {
        distributedLock.unlock();
    }
    return null;
}
Also used : DistributedLock(com.whoiszxl.DistributedLock) StockCache(com.whoiszxl.cqrs.cache.StockCache)

Aggregations

DistributedLock (com.whoiszxl.DistributedLock)4 SeckillCache (com.whoiszxl.cqrs.cache.SeckillCache)1 SeckillItemCache (com.whoiszxl.cqrs.cache.SeckillItemCache)1 StockCache (com.whoiszxl.cqrs.cache.StockCache)1 Seckill (com.whoiszxl.entity.Seckill)1 SeckillItem (com.whoiszxl.entity.SeckillItem)1 Transactional (org.springframework.transaction.annotation.Transactional)1