lua脚本操作Redis

lua脚本操作Redis

一次扣减一个商品库存

java 复制代码
**  //扣减库存
 @Test
    void test2() throws IOException {
        valueOperations.set(key,15L);
        StringBuilder sb = new StringBuilder();
        sb.append(" local key = KEYS[1]  ");
        sb.append(" local qty = ARGV[1]  ");
        sb.append(" local redis_qty = redis.call('get',key)  ");
        sb.append(" if tonumber(redis_qty) >= tonumber(qty) then  ");
        sb.append("   redis.call('decrby',key,qty) ");
        sb.append("  return  -1  ");
        sb.append(" else  ");
        sb.append("  return tonumber(redis_qty) ");  //  0, 1,2,3 ....
        sb.append(" end  ");
        sb.append("   ");
        RedisScript<Long> script = RedisScript.of(sb.toString(),Long.class);
        ExecutorService executorService = Executors.newCachedThreadPool();

        for (int i = 1; i <= 10; i++) {
            int finalI = i;
            executorService.execute(()->{
                int needQty = RandomUtil.randomInt(1, 5);
                Long qty =  stringRedisTemplate.execute(script, CollUtil.newArrayList(key), needQty+"");
             if(qty.intValue() == -1 ){
                 System.out.println("线程"+ finalI +"扣减成功,需求量是:"+needQty);
              } else {

                 System.out.println("线程"+ finalI +"扣减失败,当前库存变量是:"+qty);
             }
            });
        }


        System.in.read();
    }

一次扣减多个商品的库存

java 复制代码
void test4()  {

        StringBuilder sb = new StringBuilder();
        sb.append(" local table = {}  "); // 你要扣减的key :product.1
        sb.append(" local values =  redis.call('mget',  unpack(KEYS) )"); // [product.1,product.2]   =>  product.1 product.2
        sb.append(" for i = 1, #KEYS   do  ");
        sb.append("   if  tonumber(ARGV[i]) > tonumber(values[i])   then ");
        sb.append("     table[#table + 1] =  KEYS[i] .. '=' .. values[i] "); // product.1=23
        sb.append("   end ");
        sb.append(" end ");
        sb.append(" if #table > 0 then ");
        sb.append("   return table  ");
        sb.append(" end ");
        sb.append(" for i = 1 , #KEYS do ");
        sb.append("   redis.call('decrby',KEYS[i],ARGV[i])  ");
        sb.append(" end ");
        sb.append(" return {} ");
        RedisScript<List> luaScript = RedisScript.of(sb.toString(), List.class);

          List<StockProduct> stockProducts =  new ArrayList<>();
          stockProducts.add(new StockProduct(5,1));
          stockProducts.add(new StockProduct(4,2));

        List<String> keys = stockProducts.stream().map(it -> "product." + it.getId()).collect(Collectors.toList());
        Object[] qtys = stockProducts.stream().map(it -> it.getQty() + "").toArray();
        List<String> list = stringRedisTemplate.execute(luaScript,
                keys,
                qtys);
        if(list.isEmpty()){
            System.out.println("库存冻结成功");
        } else {

            for (String key_qty : list) {
                String[] split = key_qty.split("=");
                System.out.println(split[0] + "库存不足,剩余库存量:" + split[1]);
            }

        }


        ThreadUtil.safeSleep(3000);


    }
相关推荐
雨中飘荡的记忆2 天前
大流量下库存扣减的数据库瓶颈:Redis分片缓存解决方案
java·redis·后端
曲幽2 天前
FastAPI分布式系统实战:拆解分布式系统中常见问题及解决方案
redis·python·fastapi·web·httpx·lock·asyncio
郑州光合科技余经理7 天前
代码展示:PHP搭建海外版外卖系统源码解析
java·开发语言·前端·后端·系统架构·uni-app·php
feifeigo1237 天前
matlab画图工具
开发语言·matlab
dustcell.7 天前
haproxy七层代理
java·开发语言·前端
norlan_jame7 天前
C-PHY与D-PHY差异
c语言·开发语言
多恩Stone7 天前
【C++入门扫盲1】C++ 与 Python:类型、编译器/解释器与 CPU 的关系
开发语言·c++·人工智能·python·算法·3d·aigc
QQ4022054967 天前
Python+django+vue3预制菜半成品配菜平台
开发语言·python·django
遥遥江上月7 天前
Node.js + Stagehand + Python 部署
开发语言·python·node.js
m0_531237177 天前
C语言-数组练习进阶
c语言·开发语言·算法