欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

springboot中redis操作Hash踩坑解決

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

問題

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

但是經(jīng)過測試在第一次發(fā)送時(shí)緩存的key沒有設(shè)置過期時(shí)間,也就是說永不過期,當(dāng)再發(fā)送一次后過期時(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è)置過期時(shí)間為5分鐘
       
 
        // 判斷發(fā)送次數(shù)是否超過限制
        if (StringUtils.isNotBlank(sendCount) && Integer.parseInt(sendCount) >= 5) {
            hashOps.expire(24, TimeUnit.HOURS); // 重新設(shè)置過期時(shí)間為24H
            throw new GeneralBusinessException("發(fā)送次數(shù)過多,請24H后再試");
        }
 
        // 判斷發(fā)送頻率是否過高
        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ā)送短信過于頻繁,請稍后再試");
            }
        }
 
        // 更新發(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 將返回一個空的 BoundHashOperations 對象。這個對象仍然是可用的,但不包含任何數(shù)據(jù)。當(dāng)?shù)谝淮伟l(fā)送時(shí),上面代碼會先獲取這個key,并設(shè)置過期時(shí)間為5分鐘,但其實(shí)這個key不存在導(dǎo)致設(shè)置過期時(shí)間失敗但是沒有任何報(bào)錯,當(dāng)?shù)诙伟l(fā)送時(shí),檢查到這個key存在了,過期時(shí)間就設(shè)置成功了。

解決方案

把刷新緩存時(shí)間操作放在put數(shù)據(jù)之后,這樣保證了這個key存在后再設(shè)置過期時(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è)置過期時(shí)間
        hashOps.expire(5, TimeUnit.MINUTES); // 設(shè)置過期時(shí)間為5分鐘
       
 
    }

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

相關(guān)文章

  • Java定時(shí)任務(wù)ScheduledThreadPoolExecutor示例詳解

    Java定時(shí)任務(wù)ScheduledThreadPoolExecutor示例詳解

    這篇文章主要介紹了Java定時(shí)任務(wù)ScheduledThreadPoolExecutor示例詳解,這里使用scheduleAtFixedRate方法安排一個任務(wù),該任務(wù)是一個 Runnable 匿名類,其run方法中調(diào)用了new LoginViewTimeTask().loginStatisticsHandle()方法,需要的朋友可以參考下
    2023-11-11
  • Java新手學(xué)習(xí)之IO流的簡單使用

    Java新手學(xué)習(xí)之IO流的簡單使用

    IO主要用于設(shè)備之間的數(shù)據(jù)傳輸,Java將操作數(shù)據(jù)流的功能封裝到了IO包中,這篇文章主要給大家介紹了關(guān)于Java新手學(xué)習(xí)之IO流簡單使用的相關(guān)資料,需要的朋友可以參考下
    2021-10-10
  • 一文帶你學(xué)習(xí)Java多維數(shù)組的使用技巧

    一文帶你學(xué)習(xí)Java多維數(shù)組的使用技巧

    Java作為一門廣泛應(yīng)用于各行各業(yè)的開發(fā)語言,具有豐富的數(shù)據(jù)類型支持,其中多維數(shù)組是其重要的一種,多維數(shù)組可以更加方便地組織數(shù)據(jù),提高Java應(yīng)用程序的效率,本文將為大家介紹Java中多維數(shù)組的基本概念和常用操作,助力讀者更好地掌握多維數(shù)組的使用技巧
    2023-11-11
  • Mybatis操作多數(shù)據(jù)源的實(shí)現(xiàn)

    Mybatis操作多數(shù)據(jù)源的實(shí)現(xiàn)

    本文主要介紹了Mybatis操作多數(shù)據(jù)源,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-05-05
  • Java集合ConcurrentHashMap詳解

    Java集合ConcurrentHashMap詳解

    ConcurrentHashMap?是?J.U.C?包里面提供的一個線程安全并且高效的?HashMap,所以ConcurrentHashMap?在并發(fā)編程的場景中使用的頻率比較高
    2023-01-01
  • springboot文件虛擬路徑映射方式

    springboot文件虛擬路徑映射方式

    這篇文章主要介紹了springboot文件虛擬路徑映射方式,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-08-08
  • Java線程中synchronized和volatile關(guān)鍵字的區(qū)別詳解

    Java線程中synchronized和volatile關(guān)鍵字的區(qū)別詳解

    這篇文章主要介紹了Java線程中synchronized和volatile關(guān)鍵字的區(qū)別詳解,synchronzied既能夠保障可見性,又能保證原子性,而volatile只能保證可見性,無法保證原子性,volatile不需要加鎖,比synchronized更輕量級,不會阻塞線程,需要的朋友可以參考下
    2024-01-01
  • SpringBoot數(shù)據(jù)層測試事務(wù)回滾的實(shí)現(xiàn)流程

    SpringBoot數(shù)據(jù)層測試事務(wù)回滾的實(shí)現(xiàn)流程

    這篇文章主要介紹了SpringBoot數(shù)據(jù)層測試事務(wù)回滾的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)吧
    2022-10-10
  • 源碼解析JDK 1.8 中的 Map.merge()

    源碼解析JDK 1.8 中的 Map.merge()

    這篇文章主要介紹了JDK 1.8 之 Map.merge()的相關(guān)知識,本文給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2019-10-10
  • Java 模擬數(shù)據(jù)庫連接池的實(shí)現(xiàn)代碼

    Java 模擬數(shù)據(jù)庫連接池的實(shí)現(xiàn)代碼

    這篇文章主要介紹了Java 模擬數(shù)據(jù)庫連接池的實(shí)現(xiàn),本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-02-02

最新評論