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

 更新时间:2025年12月25日 09:12:57   作者:她说..  
本文介绍了合伙人系统中产品分配流程及其未读计数的实现方案,通过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 未读消息计数内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:

相关文章

  • redis缓存与数据库一致性的问题及解决

    redis缓存与数据库一致性的问题及解决

    这篇文章主要介绍了redis缓存与数据库一致性的问题及解决,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-06-06
  • Redis HyperLogLog数据量统计的实现实例

    Redis HyperLogLog数据量统计的实现实例

    在大数据时代,统计海量数据中的唯一值是一个常见的需求,但同时也是极具挑战性的任务,传统的统计方法可能会消耗大量内存或计算资源,而 Redis 的 HyperLogLog 数据结构 则提供了一种高效、轻量的解决方案,下面就来详细介绍一下HyperLogLog的使用,感兴趣的可以了解一下
    2025-09-09
  • Redis Key使用{}原因分析

    Redis Key使用{}原因分析

    这篇文章主要为大家介绍了Redis中Key中为什么要使用{}原因分析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-09-09
  • 详解Redis在SpringBoot工程中的综合应用

    详解Redis在SpringBoot工程中的综合应用

    这篇文章主要介绍了Redis在SpringBoot工程中的综合应用,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-10-10
  • Redis BigKey的问题解决

    Redis BigKey的问题解决

    本文主要介绍了Redis BigKey的问题解决,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-05-05
  • Redis常见性能问题及解决方案

    Redis常见性能问题及解决方案

    本文给大家介绍Redis常见性能问题及解决方案,本文结合实例代码给大家介绍的非常详细,感兴趣的朋友跟随小编一起看看吧
    2021-05-05
  • Redis主从同步配置的方法步骤(图文)

    Redis主从同步配置的方法步骤(图文)

    这篇文章主要介绍了Redis主从同步配置的方法步骤(图文),文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-02-02
  • Redis 的内存淘汰策略和过期删除策略的区别

    Redis 的内存淘汰策略和过期删除策略的区别

    这篇文章主要介绍了Redis 的内存淘汰策略和过期删除策略的区别,Redis 是可以对 key 设置过期时间的,因此需要有相应的机制将已过期的键值对删除,而做这个工作的就是过期键值删除策略
    2022-07-07
  • Springboot/Springcloud项目集成redis进行存取的过程解析

    Springboot/Springcloud项目集成redis进行存取的过程解析

    大家都知道Redis支持五种数据类型:string(字符串),hash(哈希),list(列表),set(集合),zset(sorted set:有序集合),本文重点给大家介绍Springboot/Springcloud项目集成redis进行存取的过程,需要的朋友参考下吧
    2021-12-12
  • Redis中哈希结构(Dict)的实现

    Redis中哈希结构(Dict)的实现

    本文主要介绍了Redis中哈希结构(Dict)的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-06-06

最新评论