redisson的疑问

来源:18-5 使用令牌锁防止机器人抢票

乖肥鼠Chunchilla

2023-08-16

老师您好,本节为了防止机器人抢票,使用的是redis分布式锁,可以设置锁的时间,线程结束也可以不主动释放锁。
如果改为redisson看门狗,在主线程结束的时候,如果不主动释放,锁是默认的30s后释放吗?但我实际测试的时候,同一用户抢同一车次同日期的票,发现隔了不到30s就能再次抢到令牌锁,有时候甚至隔了3秒就再次抢到令牌锁了,不知道是怎么回事

我的代码

	 /**
     * 获取令牌
     */
    public boolean validSkToken(Date date, String trainCode, Long memberId) {
        String lockKey = DateUtil.formatDate(date) + "-" + trainCode + "-" + memberId;
        // 防止机器人抢票
        RLock lock = null;
        try {
            lock = redissonClient.getLock(lockKey);
            boolean tryLock = lock.tryLock(0, TimeUnit.SECONDS); // 带看门狗
            if (tryLock) {
                LOG.info("恭喜,抢到令牌锁了!");
            } else {
                LOG.info("很遗憾,没抢到令牌锁");
                return false;
            }

            LOG.info("会员【{}】获取【{}】【{}】的令牌开始", memberId, DateUtil.formatDate(date), trainCode);
            // 令牌约等于库存,令牌没有了,就不再卖票,不需要再进入购票主流程去判断库存,判断令牌肯定比判断库存效率高
            int updateCount = skTokenMapperCust.decrease(date, trainCode);
            if (updateCount > 0) {
                return true;
            } else {
                return false;
            }
        } catch (InterruptedException e) {
            LOG.error("令牌获取异常", e);
            return false;
        } finally {
            LOG.info("此处业务不应释放令牌锁,防止机器人抢票");
        }
    }
写回答

1回答

甲蛙

2023-08-17

看门狗的话,主线程结束,守护线程也会跟着结束。

可以用redis客户端工具,查一下锁的时长是不是30秒

0
2
甲蛙
回复
乖肥鼠Chunchilla
把key打印出来,看是不是两次抢票使用的是同一个key.
2023-08-19
共2条回复

新版Springboot3.0打造能落地的高并发仿12306售票系统

最新版Spring3.0仿12306售票系统实战

852 学习 · 512 问题

查看课程