1. 程式人生 > >Redis Demo系列之(三)累加器

Redis Demo系列之(三)累加器

前言

累加器也是Redis場見的應用之一。值得注意的是Redis內的命令諸如incr等命令皆為原子操作。但是多命令組合而成的操作,為非原子操作。(如abc=incr(hello) get(hello) set(hello,abc)。此類操作需要使用MultiLua指令碼保證Redis內操作的正確性。

Demos

/**
 * 記錄Redis累加器。
 * 
 * */

public class RedisCounterDemo {

    // demo1: first not perfect
    public static Jedis jedis = new JedisPoolManager().getJedis();

    public
static long INCR_END_COUNT = 10; public static long DECR_END_COUNT = 0; // 建議操作為 自增在前 操作在後。 // 如果 操作在前 自增在後。會導致先執行操作,後判斷。易導致資料總值變多。(即秒殺時,顯示無庫存。仍然認為有。造成損失。) public static boolean increase(String key){ Long count = jedis.incr(key); if(count > INCR_END_COUNT){ // do something
return true; } return false; } public static boolean decrease(String key){ Long count = jedis.decr(key); if(count > DECR_END_COUNT){ // do something return true; } return false; } // 使用LUA 判斷 // < LUA ERROR ? why? warn the type
// have the string key first. public static boolean execLua(String key){ String script = "if tonumber(redis.call('get', KEYS[1])) > 100 then return redis.call('incr',KEYS[1]) else return 0 end"; Object result = jedis.eval(script, Collections.singletonList(key), Collections.singletonList(key)); if ((long)result > 0l) { // do something System.out.println("Hello"); return true; } return false; } // 使用multi事務進行處理 public static boolean execMulti(String key){ return false; } public static void main(String[] args) { execLua("hello"); } } //to number //https://blog.csdn.net/u013916933/article/details/54962768 //https://stackoverflow.com/questions/21707021/lua-script-for-redis-which-sums-the-values-of-keys //Exception in thread "main" redis.clients.jedis.exceptions.JedisDataException: ERR Error running script (call to f_1fb04376fc5dc524aeac5a008daa880db5104604): @user_script:1: user_script:1: attempt to compare number with nil //at redis.clients.jedis.Protocol.processError(Protocol.java:127) //at redis.clients.jedis.Protocol.process(Protocol.java:161) //at redis.clients.jedis.Protocol.read(Protocol.java:215) //at redis.clients.jedis.Connection.readProtocolWithCheckingBroken(Connection.java:340) //at redis.clients.jedis.Connection.getOne(Connection.java:322) //at redis.clients.jedis.Jedis.getEvalResult(Jedis.java:2731) //at redis.clients.jedis.Jedis.eval(Jedis.java:2671) //at redis.clients.jedis.Jedis.eval(Jedis.java:2719) //at com.yanxml.redis.demos.count.RedisCounterDemo.execLua(RedisCounterDemo.java:47) //at com.yanxml.redis.demos.count.RedisCounterDemo.main(RedisCounterDemo.java:62)

Reference