请稍等 ...
×

采纳答案成功!

向帮助你的同学说点啥吧!感谢那些助人为乐的人

redisson的疑问

老师您好,本节为了防止机器人抢票,使用的是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("此处业务不应释放令牌锁,防止机器人抢票");
        }
    }

正在回答 回答被采纳积分+3

1回答

甲蛙 2023-08-17 09:38:11

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

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

0 回复 有任何疑惑可以回复我~
  • 提问者 火尾 #1
    我在客户端里看,令牌锁使用redisson且不自动释放,下了一单成功之后,这个key会一直存在,从30s开始倒计时,到20s的时候自动又加到30s,按道理说key一直在的话应该不能再下单了?但是我手动刷单,大概每隔10s左右能成功一次,就是key从20s刷新到30s的时候。
    也就是说
    boolean tryLock = lock.tryLock(0, TimeUnit.SECONDS);
    这句话在key刷新时长的时候,返回了true。跟我想象中不太一样,我以为主线程结束之后,key应在30s后消失,这样好像更合理一点。
    回复 有任何疑惑可以回复我~ 2023-08-17 16:58:38
  • 甲蛙 回复 提问者 火尾 #2
    把key打印出来,看是不是两次抢票使用的是同一个key.
    回复 有任何疑惑可以回复我~ 2023-08-19 10:19:54
问题已解决,确定采纳
还有疑问,暂不采纳
意见反馈 帮助中心 APP下载
官方微信