Java资深学姐 2024-06-11 19:45 采纳率: 95%
浏览 5
已结题

面试必问:Redis 如何实现库存扣减操作?

面试必问:Redis 如何实现库存扣减操作?
面试必问:Redis 如何实现库存扣减操作?
面试必问:Redis 如何实现库存扣减操作?

  • 写回答

3条回答 默认 最新

  • 专家-赤兔[在线] 优质创作者: 编程框架技术领域 2024-06-11 19:45
    关注

    引自免费微信小程序:皆我百晓生

    在使用 Redis 实现库存扣减操作时,我们通常会利用 Redis 的原子性操作来确保并发环境下的数据一致性。下面是一个详细的步骤和示例代码,展示如何使用 Java 和 Jedis(一个常用的 Redis 客户端库)来实现库存扣减。

    步骤一:设置库存

    首先,在 Redis 中为每种商品设置一个库存键值对。例如,商品ID为123的商品初始库存为100个单位。

    import redis.clients.jedis.Jedis;
    
    public class InventoryManager {
        private static final String REDIS_HOST = "localhost";
        private static final int REDIS_PORT = 6379;
        private static final String KEY_PREFIX = "inventory:";
        
        public static void main(String[] args) {
            Jedis jedis = new Jedis(REDIS_HOST, REDIS_PORT);
            String key = KEY_PREFIX + "123"; // 商品ID为123的库存键
            int initialStock = 100; // 初始库存量
            
            jedis.set(key, String.valueOf(initialStock));
            System.out.println("Initial stock set for product ID: " + key);
            
            jedis.close();
        }
    }
    

    步骤二:执行库存扣减

    当用户下单时,我们需要从 Redis 中扣减库存。为了保证并发安全,我们使用 DECRBY 命令。但是,DECRBY 只有在当前库存大于等于所需数量时才应该执行,否则会导致库存负数。因此,我们使用 Lua 脚本来封装这个逻辑,确保原子性。

    public class InventoryManager {
        // ... 上面的初始化代码 ...
    
        public static void main(String[] args) {
            Jedis jedis = new Jedis(REDIS_HOST, REDIS_PORT);
            String key = KEY_PREFIX + "123";
            
            // Lua脚本
            String luaScript = 
                "local currentStock = tonumber(redis.call('GET', KEYS[1]))\n" +
                "if currentStock >= tonumber(ARGV[1]) then\n" +
                "    return redis.call('DECRBY', KEYS[1], tonumber(ARGV[1]))\n" +
                "else\n" +
                "    return 0\n" +
                "end";
            
            // 执行Lua脚本
            Object result = jedis.eval(luaScript, Collections.singletonList(key), Collections.singletonList("1")); // 减少1个单位库存
            
            if (result.equals(1L)) {
                System.out.println("Inventory deduction successful.");
            } else {
                System.out.println("Insufficient stock.");
            }
            
            jedis.close();
        }
    }
    

    注意事项

    • 使用 Lua 脚本可以保证整个操作是原子性的,即要么全部成功,要么全部失败。
    • 如果库存不足,脚本将返回 0,表示扣减失败。
    • DECRBY 命令可以减少指定的数值,但直接使用它不检查库存可能导致库存为负。

    通过上述步骤,你可以在 Redis 中安全地管理库存扣减操作,避免并发下的库存超卖问题。

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论 编辑记录
查看更多回答(2条)

报告相同问题?

问题事件

  • 系统已结题 6月19日
  • 已采纳回答 6月11日
  • 创建了问题 6月11日