社区更新聊天消息偏移量问题

    /**
     * 例如:当前偏移量为1
     * T1 读取偏移量1,更新为2,sleep 未获取分布式锁
     * T2 读取便宜量1,更新为3,更新为3。
     * <p>
     * T1 notified 获取分布式锁,更新为2。
     * <p>
     * 影响:预期为3,实际为2.
     * 所以这里使用Double Check
     */

    public void refreshReadMsgOffset(UserDO userDO, long msgId) {
        //下面是第一次更新remark如果用户没有保存remark偏移量,就直接保存
        if (StringUtils.isEmpty(userDO.getRemark())) {
            // new user
            UserRemarkBO userRemarkBO = new UserRemarkBO();
            userRemarkBO.setMsgOffsetId(msgId);
            userDAO.updateRemark(userDO.getId(), JSON.toJSONString(userRemarkBO));
            return;
        }
        //这些代码都是相对同一个用户来说的,假设传进来的userDO和msgId 的userDO都是同一个用户,msgId分别是2,3,因为前端传来的都是最新的消息偏移量,这两个线程分别为T1,T2 通过userDO.getRemark()查询到的是1,一个更新2,一个更新3,所以最终是要更新3的,如果是一个更新2,一个更新3,那么更新2的话应该也是3才对,T2所以等3更新完成之后,T1在重新获取以下最新的数据就是3,这样就避免不是最新的值,
        UserRemarkBO userRemarkBO = JSON.parseObject(userDO.getRemark(), UserRemarkBO.class);
        if (userRemarkBO.getMsgOffsetId() >= msgId) return;

        String key = LockKeyConstants.UPDATE_MSG_OFFSET_PREFIX + userDO.getId();
        Boolean locked = distributedLock.lock(key, 10, TimeUnit.SECONDS);
        if (!locked) return;
        try {
            // double check
            userDO = userDAO.getById(userDO.getId());
            userRemarkBO = JSON.parseObject(userDO.getRemark(), UserRemarkBO.class);
            if (userRemarkBO.getMsgOffsetId() >= msgId) return;
            userRemarkBO.setMsgOffsetId(msgId);
            userDAO.updateRemark(userDO.getId(), JSON.toJSONString(userRemarkBO));
        } finally {
            distributedLock.unlock(key);
        }
    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值