public class RedisLua {
public static final String STOCK_LUA;
static {
/** * 扣减库存Lua脚本(一次扣减一个库存)
* KEYS[1]:商品数量key
* KEYS[2]:订单key
* ARGV[1]:订单信息
* -1:库存不足
* -2:重复下单
* 大于等于0:剩余库存(扣减之后剩余的库存)
*/
StringBuilder sb = new StringBuilder();
sb.append("local goodsKey = KEYS[1];");
sb.append("local orderKey = KEYS[2];");
sb.append("local orderValue = ARGV[1];");
sb.append("local goodsNum = redis.call('get', goodsKey);");
sb.append("local order = redis.call('get', orderKey);");
sb.append("if goodsNum < '1' then");
sb.append(" return -1;");
sb.append("end;");
sb.append("if order == false then");
sb.append(" redis.call('set', orderKey , orderValue);");
sb.append(" return redis.call('decrBy', goodsKey, '1');");
sb.append("else");
sb.append(" return -2;");
sb.append("end;");
STOCK_LUA = sb.toString();
/**
* 扣减库存Lua脚本(一次扣减多个库存)
* KEYS[1]:商品数量key
* KEYS[2]:订单key
* ARGV[1]:扣减数量
* ARGV[2]:订单信息
* -1:库存不足
* -2:重复下单
* 大于等于0:剩余库存(扣减之后剩余的库存)
*/
/*StringBuilder sb = new StringBuilder();
sb.append("local goodsKey = KEYS[1];");
sb.append("local orderKey = KEYS[2];");
sb.append("local decrNum = ARGV[1];");
sb.append("local orderValue = ARGV[2];");
sb.append("local goodsNum = redis.call('get', goodsKey);");
sb.append("local order = redis.call('get', orderKey);");
sb.append("if goodsNum < decrNum then");
sb.append(" return -1;");
sb.append("end;");
sb.append("if order == false then");
sb.append(" redis.call('set', orderKey , orderValue);");
sb.append(" return redis.call('decrBy', goodsKey, decrNum);");
sb.append("else");
sb.append(" return -2;");
sb.append("end;");
STOCK_LUA = sb.toString();*/ }}利用
使用redisTemplate执行lua脚本
List<String> keys = Arrays.asList("goodsKey:85265602","OrderKey:457811515");
String [] arg = {"1232555"};
DefaultRedisScript<Long> stringDefaultRedisScript = new DefaultRedisScript<>();
stringDefaultRedisScript.setResultType(Long.class);
stringDefaultRedisScript.setScriptText(STOCK_LUA); // STOCK_LUA对应脚本文本
Long res = redisTemplate.execute(stringDefaultRedisScript,keys,arg);