当前位置: 代码网 > it编程>数据库>Redis > Redis实现未读消息计数的示例代码

Redis实现未读消息计数的示例代码

2025年12月25日 Redis 我要评论
一、业务场景说明在合伙人系统的产品分配流程中,存在两种分配模式,核心差异在于是否需要审核:直接分配:一级(城市合伙人)向二级(销售合伙人)分配产品,无需审核,直接生效;间接分配:二级(销售合伙人)向三

一、业务场景说明

在合伙人系统的产品分配流程中,存在两种分配模式,核心差异在于是否需要审核:

  • 直接分配:一级(城市合伙人)向二级(销售合伙人)分配产品,无需审核,直接生效;
  • 间接分配:二级(销售合伙人)向三级(流量合伙人)分配产品,必须经过对应一级(城市合伙人)审核,审核通过后分配才生效。

为提升城市合伙人的操作效率,小程序需在 “分配产品页面” 为城市合伙人显示待审核数,实时提醒其待处理的间接分配申请,而未读计数的存储与管理是实现该功能的核心。

二、未读计数的实现方案

1. 核心触发逻辑

在 “间接分配审核接口” 的最后,通过一行代码触发未读计数更新,直接调用工具类完成城市合伙人未读数量的累加:

// 添加未读数(默认新增1条待审核提醒)
appletredisutil.addunreadcount(citypartner.getid());

2. 核心工具类:appletredisutil

工具类基于 redis 实现未读计数的 “新增、查询、重置” 全流程管理,代码与逻辑解析如下:

import jakarta.annotation.resource;
import org.springblade.business.constant.rediskeyconstant;
import org.springblade.business.pojo.entity.productapplyrecord;
import org.springblade.business.service.productapplyrecordservice;
import org.springframework.data.redis.core.redistemplate;
import org.springframework.stereotype.component;
import java.util.objects;
 
@component // 注入spring容器,全局可用
public class appletredisutil {
 
    @resource
    private redistemplate<string, long> redistemplate; // 操作redis的核心组件
 
    // 1. 重载方法:默认给城市合伙人新增1条未读消息
    public void addunreadcount(long miniuserid) {
        addunreadcount(miniuserid, 1l);
    }
 
    // 2. 核心方法:支持自定义新增未读条数,含数据准确性校验
    public void addunreadcount(long miniuserid, long value) {
        // 2.1 工具类无法直接注入service,通过spring上下文获取
        productapplyrecordservice productapplyrecordservice = springcontextutil.getbean(productapplyrecordservice.class);
        
        // 2.2 查该城市合伙人的总申请数(未读上限,避免未读数超过实际总数)
        long totalcount = productapplyrecordservice.lambdaquery()
            .eq(productapplyrecord::getcitypartnerid, miniuserid)
            .count();
        
        // 2.3 查当前redis中的未读数量(空值兜底返回0,避免空指针)
        long currentunread = getunreadcount(miniuserid);
        
        // 2.4 修正未读数量:若累加后超总申请数,取总申请数(防止数据异常)
        value = (currentunread + value) > totalcount ? totalcount : (currentunread + value);
        
        // 2.5 更新redis:用“常量前缀+用户id”作为key,原子自增未读数量
        redistemplate.opsforvalue().increment(rediskeyconstant.product_apply_unread_num + miniuserid, value);
    }
 
    // 3. 查询未读数量:空值兜底,确保返回非null
    public long getunreadcount(long miniuserid) {
        string key = rediskeyconstant.product_apply_unread_num + miniuserid;
        long unread = redistemplate.opsforvalue().get(key);
        return objects.isnull(unread) ? 0l : unread;
    }
 
    // 4. 重置未读数量:先置0再删key,确保状态彻底清空
    public void resetunreadcount(long miniuserid) {
        string key = rediskeyconstant.product_apply_unread_num + miniuserid;
        redistemplate.opsforvalue().set(key, 0l);
        redistemplate.delete(key);
    }
}

工具类核心特点

  • 数据准确性:通过 “总申请数校验” 避免未读数溢出,空值兜底避免空指针;
  • 操作规范性:统一 redis key 格式(常量前缀 + 用户 id),避免 key 混乱;
  • 功能完整性:覆盖 “新增、查询、重置” 三大核心场景,支持默认 / 自定义新增条数;
  • 依赖合理性:通过 spring 上下文获取 service,解决工具类无法直接注入的问题。

三、选型:为什么用 redis 而非 mysql?

未读计数的核心诉求是 “快、并发安全、简单”,redis 完美匹配这些需求,而 mysql 更擅长 “复杂查询、事务一致性、永久存储”,具体优势对比如下:

1. 性能碾压:高频场景响应速度差 3 个量级

特性

redis(内存数据库)

mysql(磁盘数据库)

响应时间

微秒级(1μs = 10⁻⁶秒)

毫秒级(1ms = 10⁻³ 秒)

每秒读写能力

数万~数十万次

千级次

高频场景表现

无卡顿,轻松扛住并发(如同时 100 个申请提交)

易出现 “查询卡顿”“写入排队”,拖慢数据库

2. 操作更轻量:避免 mysql 复杂开销

  • redis:用 increment 原子命令,1 行代码完成 “未读数 + 1”,无需锁 / 事务;
  • mysql:需执行 update xxx set unread_count = unread_count + 1 where ...,还需处理事务隔离级别、行锁竞争,代码繁琐且开销大。

3. 天然并发安全:解决 mysql 更新冲突

当多个请求同时修改同一城市合伙人的未读计数时(如同时 2 条申请提交):

  • redis:incr 是单线程原子操作,即使 100 个请求同时 + 1,结果也绝对正确(0→100);
  • mysql:易出现 “并发更新丢失”(如两个请求同时读 5,都 + 1 后写 6,实际应是 7),需额外加 “乐观锁 / 悲观锁”,增加复杂度。

4. 缓存特性适配:减少数据库压力

  • redis:未读计数是 “缓存”,所有读写走 redis,mysql 仅存原始申请记录,极大降低 mysql 访问压力;
  • mysql:若直接存储未读数,高频读写会占用数据库资源,影响核心业务(如申请记录查询)。

5. 灵活扩展:支持更多交互场景

redis 的特性可轻松满足未来扩展需求,mysql 难以实现:

  • 过期自动清理:给未读计数 key 设 expire,实现 “30 天未读自动失效”,无需定时任务;
  • 批量操作:用 mset/mget 批量更新 / 查询多个城市合伙人的未读数,效率极高;
  • 丰富计数器操作:支持 incrby(自定义加量)、decr(减量)、getset(获取并重置),覆盖全场景。

四、注意事项:redis 数据安全兜底方案

虽然 redis 是内存数据库,但工具类已做足数据安全保障,避免数据丢失:

  1. 数据源兜底:未读计数的 “源头” 是 mysql(申请记录存在 mysql),redis 仅为缓存;
  2. 异常修正:若 redis 数据丢失,getunreadcount 会返回 0,而 addunreadcount 会重新查询 mysql 总申请数,自动修正未读计数,不会失真。

到此这篇关于redis实现未读消息计数的示例代码的文章就介绍到这了,更多相关redis 未读消息计数内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com