java 使用RedisTemplate實現Redis事務


關系型數據庫事務的作用是保證並發訪問下數據的一致性,Redis事務有些不同,由於Redis是單線程的處理來自client的指令,所以Redis所有命令的執行都是原子性的,舉一個簡單的例子,單個Redis服務器下,並發地執行INCR命令,也不會返回相同的結果。

    所以Redis事務的意義在於保證命令的批量順序執行,並且事務執行期間,Redis不會執行來自client的其他請求。有一點需要注意的是,。如果有命令執行失敗,還是會繼續執行剩下的命令,因為Redis沒有異常回滾。

    對“Redis事務命令要么全部執行,要么全部不執行”這句事實的理解:如果有命令執行失敗,並不是中斷事務,而是繼續執行剩下的指令,因為Redis不支持異常回滾。全部不執行的情況有 1.沒有執行EXEC命令 2.WATCH的key發生改變 3.DISCARD命令放棄事務。本質上開啟事務后,所有輸入的命令都被緩存在一個隊列中,一旦EXEC,隊列里的指令被一條一條的執行。

關於事務的API

  • MULTI    開啟事務
  • EXEC    執行任務隊列里所有命令,並結束事務
  • DISCARD     放棄事務,清空任務隊列,全部不執行,並UNWATCH
  • WATCH key [key1]    MULTI執行之前,指定監控某key,如果key發生修改,放棄整個事務執行
  • UNWATCH    手動取消監控

    Spring Data Redis 事務問題

    RedisTemplate來操作Redis,關於事務操作的時候會有問題:

    redisTemplate.multi();
    redisTemplate.opsForValue().increment("xxx",1);
    redisTemplate.opsForValue().increment("ttt",1);
    redisTemplate.exec();

     


    調用會報一個錯誤“No ongoing transaction. Did you forget to call multi? ”查了下,RedisTemplate操作事務不能理所當然地像原生API那么寫,其實RedisTemplate的事務需要自己實現一個SessionCallBack來做事務,所以要這么寫

    SessionCallback sessionCallback = new SessionCallback() {
        @Override
        public Object execute(RedisOperations redisOperations) throws DataAccessException {
            redisOperations.multi();
            // TODO: 2017/11/20 命令1
            // TODO: 2017/11/20 命令2
            // TODO: 2017/11/20 命令3
            return redisOperations.exec();
        }
    };
    
    redisTemplate.execute(sessionCallback);

     


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM