redis 使用lua 生成流水號

在實際的業務場景中,我們會用到流水號。
之前的流水號做法是,使用redis的全局鎖。然後對數據庫進行更新,數據庫更新 這個也會有一些問題,比如對於同一個流水號,多個線程去更新,由於事務比較長,那麼就會導致數據庫被鎖定。

這個可以使用redis的lua 腳本去解決。

由於redis 是單線程的處理模式,因此執行 lua 腳本的時候,是不會有併發問題的。

相關代碼:

點擊查看代碼
private Long getNo(String key,Integer initVal,Short step,Integer timeout){
        DefaultRedisScript<Long> redisScript= new DefaultRedisScript<>();

        //setex (key,timeout,val)
        String script="if(redis.call('exists',KEYS[1])==0) then  redis.call('setex',KEYS[1], tonumber(KEYS[4]), tonumber(KEYS[2]))  else redis.call('incrby',KEYS[1],tonumber(KEYS[3])) end  return tonumber(redis.call('get',KEYS[1]))";

        redisScript.setScriptText(script);

        List list=new ArrayList<>();
        //鍵
        list.add(key);
        //初始值
        list.add(initVal.toString());
        //步長
        list.add(step.toString());
        //超時時間
        list.add(timeout.toString());

        redisScript.setResultType(Long.class);

        Long rtn=(Long) redisTemplate.execute(redisScript,list);

        return rtn;
    }

這裏需要注意的是,KEYS 爲參數,list爲參數傳入,這裏需要保證數據的類型和redis 的函數保持一致。

另外我們需要保證redis 的存儲。

我們可以使用AOF模式

點擊查看代碼
//啓動AOf
appendonly yes
//每秒同步
appendfsync everysec
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章