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

SpringBoot使用Redis同時執(zhí)行多條命令的實現(xiàn)方法

 更新時間:2025年09月22日 09:56:58   作者:IT橘子皮  
在 Spring Boot 項目中高效、合理地使用 Redis 同時執(zhí)行多條命令,可以顯著提升應用性能,下面我將為你介紹幾種主要方式、它們的典型應用場景,以及如何在 Spring Boot 中實現(xiàn),需要的朋友可以參考下

在 Spring Boot 項目中高效、合理地使用 Redis 同時執(zhí)行多條命令,可以顯著提升應用性能。下面我將為你介紹幾種主要方式、它們的典型應用場景,以及如何在 Spring Boot 中實現(xiàn)。

首先,我們來通過一個表格快速了解這幾種方式的特點和適用場景:

方式原子性主要優(yōu)勢Spring Boot 中的典型應用場景
?Pipeline (管道)??大幅提升批量操作效率,減少網絡往返次數緩存預熱、批量數據導入導出、無依賴關系的批量查詢
?事務 (Transaction)??部分命令隊列化,保證連續(xù)執(zhí)行(但不支持回滾)簡單的原子操作序列,如庫存扣減、更新多個相關鍵
?Lua 腳本?復雜邏輯原子執(zhí)行,避免中間狀態(tài),性能高分布式鎖、秒殺、需要原子性的復雜業(yè)務邏輯

1. Pipeline (管道)

Pipeline 允許客戶端將多個命令打包后一次性發(fā)送給 Redis 服務器,服務器依次執(zhí)行后再次將所有結果一次性返回給客戶端。這能顯著減少網絡往返次數(RTT)?,從而大幅提升吞吐量,尤其在高延遲網絡環(huán)境下效果明顯。

?Spring Boot 實現(xiàn)示例:??

import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.stereotype.Service;
import java.util.List;

@Service
public class RedisPipelineService {

    private final StringRedisTemplate stringRedisTemplate;

    // 構造器注入
    public RedisPipelineService(StringRedisTemplate stringRedisTemplate) {
        this.stringRedisTemplate = stringRedisTemplate;
    }

    public void batchSetKeys(List<String> keys, List<String> values) {
        // 使用 executePipelined 方法執(zhí)行管道操作
        List<Object> results = stringRedisTemplate.executePipelined((RedisCallback<Object>) connection -> {
            for (int i = 0; i < keys.size(); i++) {
                connection.set(keys.get(i).getBytes(), values.get(i).getBytes());
            }
            return null; // 回調中返回 null
        });
        // results 包含每個命令的執(zhí)行結果
    }
}

?使用場景:??

  • ?緩存預熱?:應用啟動時批量加載熱點數據到 Redis。
  • ?批量數據導入/導出?:例如從數據庫批量導入數據到 Redis,或從 Redis 批量獲取數據進行處理。
  • ?批量查詢無關聯(lián)數據?:一次性獲取多個不相關鍵的值,減少網絡開銷。

?注意事項:??

  • Pipeline 中的命令不具備原子性
  • 建議單次 Pipeline 命令數控制在合理范圍內(如幾千條),避免服務器內存壓力或客戶端長時間阻塞。
  • ?錯誤處理?:某個命令失敗不會影響 Pipeline 中其他命令的執(zhí)行,需要在客戶端解析結果列表時逐一檢查。

2. 事務 (Transaction)

Redis 事務通過 MULTI, EXEC, DISCARD, WATCH等命令實現(xiàn)。它允許將多個命令放入一個隊列,然后通過 EXEC命令原子性地順序執(zhí)行這些命令。

?Spring Boot 實現(xiàn)示例:??

Spring Data Redis 提供了 SessionCallback接口來支持在同一個連接中執(zhí)行多個操作,這對于事務至關重要。

import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.SessionCallback;
import org.springframework.stereotype.Service;
import java.util.List;

@Service
public class RedisTransactionService {

    private final RedisTemplate<String, Object> redisTemplate;

    public RedisTransactionService(RedisTemplate<String, Object> redisTemplate) {
        this.redisTemplate = redisTemplate;
    }

    public List<Object> executeInTransaction() {
        // 使用 execute 方法并傳遞 SessionCallback 來執(zhí)行事務
        SessionCallback<List<Object>> sessionCallback = new SessionCallback<>() {
            @Override
            public List<Object> execute(org.springframework.data.redis.core.RedisOperations operations) {
                operations.multi(); // 開啟事務
                operations.opsForValue().set("key1", "value1");
                operations.opsForValue().increment("counter");
                operations.opsForSet().add("setKey", "member1");
                return operations.exec(); // 執(zhí)行事務并返回結果
            }
        };
        return redisTemplate.execute(sessionCallback);
    }
}

?使用場景:??

  • ?簡單的原子操作序列?:需要確保一系列命令連續(xù)執(zhí)行,不被其他命令打斷,但不要求所有命令必須全部成功?(例如,扣減庫存后增加銷量)。
  • ?結合 WATCH實現(xiàn)樂觀鎖?:監(jiān)控特定鍵,如秒殺場景中監(jiān)控庫存鍵,防止超賣。
// 結合 WATCH 的樂觀鎖示例
public boolean watchAndExecute(String key, String expectedValue, String newValue) {
    return redisTemplate.execute(new SessionCallback<Boolean>() {
        @Override
        public Boolean execute(RedisOperations operations) {
            operations.watch(key); // 監(jiān)視 key
            String currentValue = (String) operations.opsForValue().get(key);
            if (expectedValue.equals(currentValue)) {
                operations.multi();
                operations.opsForValue().set(key, newValue);
                List<Object> execResult = operations.exec(); // 如果 execResult 為空,表示事務執(zhí)行失敗(鍵被修改)
                return execResult != null && !execResult.isEmpty();
            }
            operations.unwatch();
            return false;
        }
    });
}

?注意事項:??

  • Redis 事務不支持回滾 (Rollback)?。如果在執(zhí)行過程中某個命令失敗,已執(zhí)行的命令不會回滾,后續(xù)命令仍會繼續(xù)執(zhí)行。
  • ?錯誤類型?:
    • ?入隊錯誤?(如命令語法錯誤):在執(zhí)行 EXEC前,Redis 可能會檢查出錯誤并放棄整個事務。
    • ?運行時錯誤?(如數據類型操作錯誤):在 EXEC后執(zhí)行中發(fā)生的錯誤,Redis 會記錄錯誤信息但不會中斷事務執(zhí)行。

3. Lua 腳本

Redis 支持執(zhí)行 ?Lua 腳本。腳本中的所有命令會作為一個整體原子性地執(zhí)行,期間不會被其他命令打斷,是原子性最強的方案,同時還能減少網絡往返。

?Spring Boot 實現(xiàn)示例:??

RedisTemplate提供了 execute方法用于執(zhí)行 Lua 腳本。

import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;
import org.springframework.stereotype.Service;
import java.util.Arrays;

@Service
public class RedisLuaService {

    private final RedisTemplate<String, Object> redisTemplate;

    public RedisLuaService(RedisTemplate<String, Object> redisTemplate) {
        this.redisTemplate = redisTemplate;
    }

    public String useLuaScript() {
        // 定義 Lua 腳本字符串
        String luaScript = """
                local key1 = KEYS[1]
                local value1 = ARGV[1]
                redis.call('set', key1, value1)
                local value = redis.call('get', key1)
                redis.call('incr', 'counter')
                return value
                """;
        
        DefaultRedisScript<String> script = new DefaultRedisScript<>();
        script.setScriptText(luaScript);
        script.setResultType(String.class); // 設置返回值類型

        // 執(zhí)行腳本,傳入 keys 和 args 數組
        String result = redisTemplate.execute(script, Arrays.asList("myKey"), "myValue");
        return result; // 返回腳本執(zhí)行結果
    }
}

?使用場景:??

?釋放分布式鎖?:確保判斷鎖標識和刪除鎖是一個原子操作。

-- KEYS[1] 是鎖的key,ARGV[1]是當前持有者的標識
if redis.call("get", KEYS[1]) == ARGV[1] then
    return redis.call("del", KEYS[1])
else
    return 0
end

?秒殺/搶購?:判斷庫存和扣減庫存需要原子性。

?復雜業(yè)務邏輯?:需要多個命令的中間結果進行邏輯判斷。

?注意事項:??

  • ?腳本應盡量簡單快速?:執(zhí)行 Lua 腳本會阻塞 Redis,長時間運行的腳本會影響性能。
  • ?注意腳本的復用?:Redis 會緩存編譯過的腳本,可以使用 EVALSHA通過腳本摘要來執(zhí)行,減少帶寬。DefaultRedisScript對象通常會被配置為單例,Spring 會智能地處理 EVALEVALSHA。

如何選擇?

  • ?追求極致性能,批量處理無關聯(lián)命令?:選擇 ?Pipeline。
  • ?需要保證一系列命令連續(xù)執(zhí)行(簡單原子性),且不介意無回滾?:選擇事務?(可配合 `WATCH**)。
  • ?需要保證復雜操作原子性,或操作依賴于中間結果?:選擇 ?Lua 腳本。

集群環(huán)境特別注意

在 Redis Cluster 模式下,使用事務 (Transaction) 或 Lua 腳本時,?所有涉及的鍵必須在同一個哈希槽 (hash slot) 上,否則會報錯。 可以通過 ?hash tag? 確保不同的鍵分配到同一個槽。

以上就是SpringBoot使用Redis同時執(zhí)行多條命令的實現(xiàn)方法的詳細內容,更多關于SpringBoot Redis同時執(zhí)行多條命令的資料請關注腳本之家其它相關文章!

相關文章

  • Java中的lambda和stream實現(xiàn)排序

    Java中的lambda和stream實現(xiàn)排序

    這篇文章主要介紹了Java中的lambda和stream實現(xiàn)排序,文章圍繞主題展開詳細的內容介紹,具有一定的參考價值,需要的小伙伴可以參考一下
    2022-09-09
  • Java JDBC基本使用方法詳解

    Java JDBC基本使用方法詳解

    這篇文章主要介紹了Java JDBC基本使用方法,結合實例形式詳細分析了java JDBC基本原理、用法及操作注意事項,需要的朋友可以參考下
    2020-04-04
  • java.lang.InterruptedException異常的問題解決

    java.lang.InterruptedException異常的問題解決

    本文主要介紹了java.lang.InterruptedException異常的問題解決,這種異常通常意味著 Jenkins 任務在執(zhí)行過程中被中斷,這可能會導致任務失敗或中止,下面就來介紹一下解決方法,感興趣的可以了解一下
    2024-07-07
  • 使用注解@Validated效驗VO參數是否合規(guī)

    使用注解@Validated效驗VO參數是否合規(guī)

    這篇文章主要為大家介紹了使用注解@Validated效驗VO參數是否合規(guī)過程詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-05-05
  • Java線程池框架核心代碼解析

    Java線程池框架核心代碼解析

    這篇文章主要針對Java線程池框架核心代碼進行詳細解析,分析Java線程池框架的實現(xiàn)ThreadPoolExecutor,感興趣的小伙伴們可以參考一下
    2016-07-07
  • java開發(fā)分布式服務框架Dubbo調用過程

    java開發(fā)分布式服務框架Dubbo調用過程

    這篇文章主要為大家介紹了java開發(fā)分布式服務框架Dubbo調用過程,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步早日升職加薪
    2021-11-11
  • SpringBoot+MybatisPlus+代碼生成器整合示例

    SpringBoot+MybatisPlus+代碼生成器整合示例

    這篇文章主要介紹了SpringBoot+MybatisPlus+代碼生成器整合示例,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-03-03
  • 基于Java開發(fā)一個Markdown到Word文檔轉換工具

    基于Java開發(fā)一個Markdown到Word文檔轉換工具

    本文介紹了一個用Java開發(fā)的Markdown到Word文檔轉換工具,該工具通過MarkdownToWordConverter類實現(xiàn),利用flexmark庫將Markdown內容轉換為HTML,借助jsoup庫規(guī)范化HTML,再通過docx4j庫將處理后的HTML導入并保存為Word文檔,需要的朋友可以參考下
    2025-07-07
  • Java實現(xiàn)的斷點續(xù)傳功能的示例代碼

    Java實現(xiàn)的斷點續(xù)傳功能的示例代碼

    本篇文章主要介紹了Java實現(xiàn)的斷點續(xù)傳功能的示例代碼,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-02-02
  • IDEA 2019.2.2配置Maven3.6.2打開Maven項目出現(xiàn) Unable to import Maven project的問題

    IDEA 2019.2.2配置Maven3.6.2打開Maven項目出現(xiàn) Unable to import Maven

    這篇文章主要介紹了IDEA 2019.2.2配置Maven3.6.2打開Maven項目出現(xiàn) Unable to import Maven project的問題,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-12-12

最新評論