Lua脚本
lua是一个小巧的脚本语言,其设计目的是为了通过灵活嵌入应用程序中从而为应用程序提供灵活的扩展和定制功能,lua由标准c编写而成,几乎在所有操作系统和平台上都可以编译、运行,reids2.6版本后内嵌了对lua环境的支持,解决了长久以来不能高效地处理cas(check-and-set)命令的缺点,并且可以通过组合使用多个命令,轻松实现以前很难实现或者不能高效实现的模式。
其优点包含:
- 轻量级:其中只包含一个精简的内核和最基本的库,体积小、速度快,从而适合嵌入在别的程序里
- 可扩展:Lua提供了非常易于使用的扩展接口和机制
- 减少网络开销:可以将多个请求通过脚本的形式一次发送,减少网络时延和请求次数
- 原子性的操作:Redis会将整个脚本作为一个整体执行,中间不会被其他命令插入。因此在编写脚本的过程中无需担心会出现竞态条件,无需使用事务
在业务中的应用
1.创建Lua脚本
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);");