最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

springboot中redis操作Hash踩坑解決

 更新時(shí)間:2024年06月27日 09:27:50   作者:蒾酒  
本文主要介紹了springboot中redis操作Hash踩坑解決,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧

問(wèn)題

如下代碼是獲取短信驗(yàn)證碼功能,會(huì)先檢查下前面五分鐘內(nèi)發(fā)沒(méi)發(fā)過(guò)驗(yàn)證碼,也就是有沒(méi)有手機(jī)號(hào)對(duì)應(yīng)緩存key,有的話(huà)刷新過(guò)期時(shí)間,沒(méi)有就緩存一下設(shè)置過(guò)期時(shí)間為5分鐘。

但是經(jīng)過(guò)測(cè)試在第一次發(fā)送時(shí)緩存的key沒(méi)有設(shè)置過(guò)期時(shí)間,也就是說(shuō)永不過(guò)期,當(dāng)再發(fā)送一次后過(guò)期時(shí)間就正常刷新為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); // 設(shè)置過(guò)期時(shí)間為5分鐘
       
 
        // 判斷發(fā)送次數(shù)是否超過(guò)限制
        if (StringUtils.isNotBlank(sendCount) && Integer.parseInt(sendCount) >= 5) {
            hashOps.expire(24, TimeUnit.HOURS); // 重新設(shè)置過(guò)期時(shí)間為24H
            throw new GeneralBusinessException("發(fā)送次數(shù)過(guò)多,請(qǐng)24H后再試");
        }
 
        // 判斷發(fā)送頻率是否過(guò)高
        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("發(fā)送短信過(guò)于頻繁,請(qǐng)稍后再試");
            }
        }
 
        // 更新發(fā)送次數(shù)
        int newSendCount = StringUtils.isNotBlank(sendCount) ? Integer.parseInt(sendCount) + 1 : 1;
 
        // 生成新驗(yàn)證碼
        if (StringUtils.isBlank(captcha)) {
            captcha = RandomStringUtils.randomNumeric(6);
        }
 
        // 發(fā)送短信
        if (!smsUtil.sendSms(phone, captcha)) {
            throw new GeneralBusinessException("發(fā)送短信失敗");
        }
 
        // 更新 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 方法時(shí)指定的 hashKey 在 Redis 中不存在,那么 boundHashOps 將返回一個(gè)空的 BoundHashOperations 對(duì)象。這個(gè)對(duì)象仍然是可用的,但不包含任何數(shù)據(jù)。當(dāng)?shù)谝淮伟l(fā)送時(shí),上面代碼會(huì)先獲取這個(gè)key,并設(shè)置過(guò)期時(shí)間為5分鐘,但其實(shí)這個(gè)key不存在導(dǎo)致設(shè)置過(guò)期時(shí)間失敗但是沒(méi)有任何報(bào)錯(cuò),當(dāng)?shù)诙伟l(fā)送時(shí),檢查到這個(gè)key存在了,過(guò)期時(shí)間就設(shè)置成功了。

解決方案

把刷新緩存時(shí)間操作放在put數(shù)據(jù)之后,這樣保證了這個(gè)key存在后再設(shè)置過(guò)期時(shí)間。

@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));
        //設(shè)置數(shù)據(jù)后再設(shè)置過(guò)期時(shí)間
        hashOps.expire(5, TimeUnit.MINUTES); // 設(shè)置過(guò)期時(shí)間為5分鐘
       
 
    }

到此這篇關(guān)于spring boot中redis操作Hash踩坑解決的文章就介紹到這了,更多相關(guān)springboot redis操作Hash內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家! 

相關(guān)文章

  • Java中instanceof關(guān)鍵字的用法總結(jié)

    Java中instanceof關(guān)鍵字的用法總結(jié)

    instanceof是Java的一個(gè)二元操作符,和==,>,<是同一類(lèi)東東。由于它是由字母組成的,所以也是Java的保留關(guān)鍵字。它的作用是測(cè)試它左邊的對(duì)象是否是它右邊的類(lèi)的實(shí)例,返回boolean類(lèi)型的數(shù)據(jù)
    2013-10-10
  • 通過(guò)實(shí)例了解java TransferQueue

    通過(guò)實(shí)例了解java TransferQueue

    這篇文章主要介紹了TransferQueue實(shí)例,下面小編和大家一起來(lái)學(xué)習(xí)一下
    2019-05-05
  • Java中的DelayQueue源碼解析

    Java中的DelayQueue源碼解析

    這篇文章主要介紹了Java中的DelayQueue源碼解析,一個(gè)實(shí)現(xiàn)PriorityBlockingQueue實(shí)現(xiàn)延遲獲取的無(wú)界隊(duì)列,在創(chuàng)建元素時(shí),可以指定多久才能從隊(duì)列中獲取當(dāng)前元素,只有延時(shí)期滿(mǎn)后才能從隊(duì)列中獲取元素,需要的朋友可以參考下
    2023-12-12
  • Java在運(yùn)行時(shí)識(shí)別類(lèi)型信息的方法詳解

    Java在運(yùn)行時(shí)識(shí)別類(lèi)型信息的方法詳解

    這篇文章主要給大家介紹了關(guān)于Java在運(yùn)行時(shí)識(shí)別類(lèi)型信息的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考借鑒,下面來(lái)一起看看吧
    2019-01-01
  • Java內(nèi)部類(lèi)知識(shí)匯總

    Java內(nèi)部類(lèi)知識(shí)匯總

    在Java中,在類(lèi)內(nèi)部可以定義成員變量與方法,還可以在類(lèi)的內(nèi)部定義類(lèi).這種在類(lèi)的內(nèi)部定義的類(lèi)稱(chēng)為內(nèi)部類(lèi).而內(nèi)部類(lèi)所在的類(lèi)稱(chēng)為外部類(lèi).
    2018-03-03
  • Java守護(hù)線(xiàn)程(Daemon Thread)的實(shí)現(xiàn)示例

    Java守護(hù)線(xiàn)程(Daemon Thread)的實(shí)現(xiàn)示例

    本文主要介紹了Java守護(hù)線(xiàn)程(Daemon Thread)的實(shí)現(xiàn)示例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2025-11-11
  • Java高性能實(shí)體類(lèi)轉(zhuǎn)換工具M(jìn)apStruct的使用教程詳解

    Java高性能實(shí)體類(lèi)轉(zhuǎn)換工具M(jìn)apStruct的使用教程詳解

    MapStruct 是一個(gè)代碼生成器,它基于約定優(yōu)于配置的方法,極大地簡(jiǎn)化了 Java bean 類(lèi)型之間的映射實(shí)現(xiàn),本文主要介紹了MapStruct的具體使用以及如何進(jìn)行實(shí)體類(lèi)轉(zhuǎn)換,感興趣的可以了解下
    2024-03-03
  • JavaWeb JDBC + MySql 通訊錄實(shí)現(xiàn)簡(jiǎn)單的增刪改查功能案例詳解

    JavaWeb JDBC + MySql 通訊錄實(shí)現(xiàn)簡(jiǎn)單的增刪改查功能案例詳解

    這篇文章主要介紹了JavaWeb JDBC + MySql 通訊錄實(shí)現(xiàn)簡(jiǎn)單的增刪改查功能,結(jié)合具體案例形式詳細(xì)分析了JavaWeb JDBC + MySql數(shù)據(jù)庫(kù)連接、增刪改查等相關(guān)操作技巧與注意事項(xiàng),需要的朋友可以參考下
    2019-08-08
  • Java語(yǔ)言實(shí)現(xiàn)基數(shù)排序代碼分享

    Java語(yǔ)言實(shí)現(xiàn)基數(shù)排序代碼分享

    這篇文章主要介紹了Java語(yǔ)言實(shí)現(xiàn)基數(shù)排序代碼分享,具有一定借鑒價(jià)值,需要的朋友可以參考下。
    2017-12-12
  • Java日期毫秒值和常見(jiàn)日期時(shí)間格式相互轉(zhuǎn)換方法

    Java日期毫秒值和常見(jiàn)日期時(shí)間格式相互轉(zhuǎn)換方法

    這篇文章主要給大家介紹了關(guān)于Java日期毫秒值和常見(jiàn)日期時(shí)間格式相互轉(zhuǎn)換的相關(guān)資料,在Java的日常開(kāi)發(fā)中,會(huì)隨時(shí)遇到需要對(duì)時(shí)間處理的情況,文中給出了詳細(xì)的示例代碼,需要的朋友可以參考下
    2023-07-07

最新評(píng)論

卓尼县| 桐梓县| 阳高县| 深水埗区| 怀化市| 农安县| 朔州市| 西丰县| 赤城县| 衡东县| 财经| 苗栗市| 沁源县| 抚顺县| 祁连县| 耒阳市| 蒙自县| 石阡县| 桐梓县| 新竹县| 浪卡子县| 阳江市| 乌什县| 托克托县| 六枝特区| 永定县| 泸定县| 阿勒泰市| 阿荣旗| 朝阳县| 沧州市| 卓尼县| 青川县| 呼玛县| 柳林县| 喀喇| 新晃| 台前县| 武邑县| 广安市| 乐亭县|