场景:一个商品对应库存数量为 10,一个用户id,只能购买一次
脚本逻辑:
- 先检查当前用户ID,是否已经存在,如果存在,直接返回 -1
- 如果不存在,则查询库存数量,判断库存数量是否大于0,如果大于0,才能进行减库存
- 扣减成功,则将用户ID,写入缓存,同时返回 1
- 如果库存数量已经为0了,则直接返回 0
@Test
void decrementStock4() {
String threadName0 = getThreadName0(); // 这里可以换成购买人的id
String stockKey = "stock";
// 定义 Lua 脚本
String script = "local exist = redis.call('EXISTS', KEYS[2])\n"
+ "if exist == 1 then\n"
+ " return -1\n"
+ "end\n"
+ "local currentStock = tonumber(redis.call('GET', KEYS[1]))\n"
+ "local decrement = tonumber(KEYS[3])\n"
+ "if currentStock > 0 then\n"
+ " redis.call('DECRBY', KEYS[1], decrement)\n"
+ " redis.call('SET', KEYS[2], 'true')\n"
+ " return 1\n"
+ "else\n"
+ " return 0\n"
+ "end";
// 执行 Lua 脚本
RScript rScript = redissonClient.getScript();
Long result = rScript.eval(RScript.Mode.READ_WRITE, script, RScript.ReturnType.INTEGER,
Arrays.asList(stockKey, threadName0, "1"));
// 判断执行结果
if (result == 1) {
System.out.println("OK::" + threadName0 + " 库存扣减成功");
} else if (result == 0) {
System.out.println("ERR::" + threadName0 + "库存不足,无法扣减");
} else {
System.out.println("ERR::" + threadName0 + "已经扣过库存,无需重复扣减");
}
}