1. 程式人生 > >Redisson lua指令碼執行踩坑之神祕的引號

Redisson lua指令碼執行踩坑之神祕的引號

最近專案需求,在redis中需要執行批量刪除指定key,並且要支援原子操作,那麼當然只有自己寫lua指令碼了。

專案中使用的是redisson作為redis連線工具,首先先定義好lua指令碼:

   private static final String BATCH_DEL_SCRIPT = "for k,v in  pairs(ARGV) do \n " +
            "redis.call('del',v) \n" +
            "end \n" +
            "return #ARGV";

指令碼很簡單,根據引數傳入的key,進行迴圈刪除,然後返回引數的數量,當然這裡也可以改為返回刪除的數量總和。
redisson使用:

     redissonClient.getScript().evalAsync(RScript.Mode.READ_WRITE, BATCH_DEL_SCRIPT, RScript.ReturnType.INTEGER, keys, keys.toArray());
     

然後開始執行以上程式碼,就是死活刪除不了指定的key,比如redis中存在key:aaaa,執行命令後aaaa還在。各種調查和學習lua語法後還是不行。於是轉換思路,不執行刪除,而是將刪除操作修改為賦值操作,只要將資料置為空也可以達到效果。於是指令碼變為:

   private static final String BATCH_DEL_SCRIPT = "for k,v in  pairs(ARGV) do \n " +
            "redis.call('set',v,'') \n" +
            "end \n" +
            "return #ARGV";

通過以上指令碼執行後,還是不行,aaaa還存在,而且重新整理後多了key:“aaaa”。什麼鬼!!
怎麼多了個key值,而且是加了引號的。一臉悶逼中。

知道了設定的規則後,那麼解決辦法就簡單了,只需要在設定或刪除key之前去除多餘的引號就好了,於是指令碼改為:

   private static final String BATCH_DEL_SCRIPT = "for k,v in  pairs(ARGV) do \n " +
            "redis.call('del',string.gsub(v,'\"',''),'') \n" +
            "end \n" +
            "return #ARGV";

這樣完美解決。

至於為什麼lua指令碼執行後,字串物件為什麼會多了雙引號,這個還在調查中,如果你知道,歡迎評論告知,不勝感激。