Redis Demo系列之(三)累加器
阿新 • • 發佈:2019-02-15
前言
累加器也是Redis場見的應用之一。值得注意的是Redis內的命令諸如incr
等命令皆為原子操作。但是多命令組合而成的操作,為非原子操作。(如abc=incr(hello) get(hello) set(hello,abc)。此類操作需要使用Multi
或Lua
指令碼保證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)