当前位置: 代码网 > it编程>编程语言>Java > springboot中redis操作Hash踩坑解决

springboot中redis操作Hash踩坑解决

2024年07月02日 Java 我要评论
问题如下代码是获取短信验证码功能,会先检查下前面五分钟内发没发过验证码,也就是有没有手机号对应缓存key,有的话刷新过期时间,没有就缓存一下设置过期时间为5分钟。但是经过测试在第一次发送时缓存的key

问题

如下代码是获取短信验证码功能,会先检查下前面五分钟内发没发过验证码,也就是有没有手机号对应缓存key,有的话刷新过期时间,没有就缓存一下设置过期时间为5分钟。

但是经过测试在第一次发送时缓存的key没有设置过期时间,也就是说永不过期,当再发送一次后过期时间就正常刷新为5分钟了。

 @override
    public void getsmscaptcha(string phone) {
        string hashkey = "login:sms:captcha:" + phone;
        boundhashoperations<string, string, string> hashops = stringredistemplate.boundhashops(hashkey);
 
        // 初始检查
        string lastsendtimestamp = hashops.get("lastsendtimestamp");
        string sendcount = hashops.get("sendcount");
        string captcha = hashops.get("captcha");
        hashops.expire(5, timeunit.minutes); // 设置过期时间为5分钟
       
 
        // 判断发送次数是否超过限制
        if (stringutils.isnotblank(sendcount) && integer.parseint(sendcount) >= 5) {
            hashops.expire(24, timeunit.hours); // 重新设置过期时间为24h
            throw new generalbusinessexception("发送次数过多,请24h后再试");
        }
 
        // 判断发送频率是否过高
        if (stringutils.isnotblank(lastsendtimestamp)) {
            long lastsendtime = long.parselong(lastsendtimestamp);
            long currenttime = system.currenttimemillis();
            long elapsedtime = currenttime - lastsendtime;
            long interval = 60 * 1000; // 60秒
            if (elapsedtime < interval) {
                throw new generalbusinessexception("发送短信过于频繁,请稍后再试");
            }
        }
 
        // 更新发送次数
        int newsendcount = stringutils.isnotblank(sendcount) ? integer.parseint(sendcount) + 1 : 1;
 
        // 生成新验证码
        if (stringutils.isblank(captcha)) {
            captcha = randomstringutils.randomnumeric(6);
        }
 
        // 发送短信
        if (!smsutil.sendsms(phone, captcha)) {
            throw new generalbusinessexception("发送短信失败");
        }
 
        // 更新 redis 中的信息
        hashops.put("captcha", captcha);
        hashops.put("lastsendtimestamp", string.valueof(system.currenttimemillis()));
        hashops.put("sendcount", string.valueof(newsendcount));
       
 
    }

原因

boundhashoperations<string, string, string> hashops = stringredistemplate.boundhashops(hashkey);

使用 boundhashops 方法时指定的 hashkey 在 redis 中不存在,那么 boundhashops 将返回一个空的 boundhashoperations 对象。这个对象仍然是可用的,但不包含任何数据。当第一次发送时,上面代码会先获取这个key,并设置过期时间为5分钟,但其实这个key不存在导致设置过期时间失败但是没有任何报错,当第二次发送时,检查到这个key存在了,过期时间就设置成功了。

解决方案

把刷新缓存时间操作放在put数据之后,这样保证了这个key存在后再设置过期时间。

@override
    public void getsmscaptcha(string phone) {
        string hashkey = "login:sms:captcha:" + phone;
        boundhashoperations<string, string, string> hashops = stringredistemplate.boundhashops(hashkey);
 
        // 初始检查
        string lastsendtimestamp = hashops.get("lastsendtimestamp");
        string sendcount = hashops.get("sendcount");
        string captcha = hashops.get("captcha");
      
        //。。。。。。。。。。。。。。。。。。。。。。。
         
        // 更新 redis 中的信息
        hashops.put("captcha", captcha);
        hashops.put("lastsendtimestamp", string.valueof(system.currenttimemillis()));
        hashops.put("sendcount", string.valueof(newsendcount));
        //设置数据后再设置过期时间
        hashops.expire(5, timeunit.minutes); // 设置过期时间为5分钟
       
 
    }

到此这篇关于spring boot中redis操作hash踩坑解决的文章就介绍到这了,更多相关springboot redis操作hash内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网! 

(0)

相关文章:

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

发表评论

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