前言在工贸业务微服务架构开发场景中ERP 进销存属于数据一致性要求较高的核心业务模块并发场景下库存超卖、多单据数据同步异常、多租户数据隔离失效是开发过程中普遍存在的技术难点。现有不少开源项目将库存业务逻辑与基础框架深度耦合缺少标准化并发控制逻辑在多租户 SaaS 架构中容易出现库存数据错乱问题。本文基于 EzCloud 开源项目中独立拆分的ez-cloud-erp插件模块梳理采购、销售、库存、调拨、盘点全链路实现逻辑模块内置分布式锁、事件驱动单据事务联动相关实现全部源码可用于技术调试与方案参考。ERP 模块源码目录参考https://gitee.com/tan-tianming/ez-cloud/tree/master/ez-cloud-erp1、EzCloud ERP 模块工程分层结构erp 模块内部三层业务拆分各层级职责完全隔离erp-purchase承载采购申请、采购订单、采购入库、采购退货单据相关逻辑erp-sales承载销售订单、销售出库、销售退货、客户对账相关逻辑erp-stock库存核心底层服务统一封装库存台账、批次管理、库存扣减、盘点、分布式锁能力架构设计统一约束所有库存数值变更逻辑仅允许在 erp-stock 服务内执行采购、销售模块仅完成单据持久化通过标准接口调用库存能力避免多业务重复编写库存操作逻辑降低代码冗余。2、核心源码分布式并发库存扣减实现仓库 erp-stock 核心代码java运行Service public class StockServiceImpl implements StockService { Autowired private StockMapper stockMapper; Autowired private RedisTemplateString, Object redisTemplate; Autowired private TransactionStatus transactionStatus; // 分布式锁Key前缀 private static final String STOCK_LOCK_PREFIX erp:stock:lock:; Override GlobalTransactional // Seata分布式事务注解 public void deductStock(Long goodsId, Integer num, Long tenantId) { String lockKey STOCK_LOCK_PREFIX tenantId : goodsId; // 获取Redis分布式锁规避并发超卖问题 boolean lock RedisLockUtil.tryLock(lockKey, 30, TimeUnit.SECONDS); if (!lock) { throw new BusinessException(当前操作人数过多请稍后重试); } try { // 查询当前租户商品可用库存 StockDO stock stockMapper.selectByGoodsIdAndTenant(goodsId, tenantId); if (stock.getAvailableNum() num) { throw new BusinessException(商品库存不足); } // 扣减可用库存增加占用库存 stock.setAvailableNum(stock.getAvailableNum() - num); stock.setOccupyNum(stock.getOccupyNum() num); stockMapper.updateById(stock); // 新增库存变动流水记录 StockRecordDO record buildStockRecord(goodsId, num, StockOperateType.SALE_OUT); stockRecordMapper.insert(record); } finally { RedisLockUtil.unLock(lockKey); } } }代码设计技术特点锁与查询条件携带租户 ID天然实现不同租户库存数据逻辑隔离借助 Redis 分布式锁拦截同一商品并发扣减请求解决并发超卖缺陷基于 Seata 分布式事务保障库存更新、流水记录操作原子执行避免单表更新造成数据不一致拆分可用库存、占用库存双字段锁定未完成出库订单对应库存规避重复售卖逻辑漏洞。3、单据自动联动机制采购入库自动回写库存EzCloud ERP 模块采用事件监听模式解耦单据与库存逻辑不存在硬编码依赖采购入库单审核流程完成后系统发布入库业务事件stock 服务统一监听对应事件异步执行商品库存增量更新采购退货单据审核完成后反向执行库存扣减逻辑整套事件通信基于 RocketMQ 异步实现单据服务与库存服务完全解耦。后续拓展委外加工、门店调拨等新单据类型时仅新增对应事件发布与监听逻辑无需修改原有库存核心实现代码。4、模块拓展设计特点仅针对 ERP 模块独立设计不重复全局架构内容库存操作逻辑统一封装拓展行业单据时无需重复编写库存扣减、台账记录逻辑预留商品批次、序列号拓展字段如需实现一物一码管理仅扩展数据表字段核心库存扣减代码无需改动内置库存预警、安全库存配置相关接口可对接项目内置低代码表单、报表模块ERP 属于独立插件工程若业务场景无需进销存相关功能可移除对应 Maven 依赖不会干扰权限、流程等底层基础服务正常运行。技术资源参考ERP 完整模块源码目录https://gitee.com/tan-tianming/ez-cloud/tree/master/ez-cloud-erp库存并发控制、单据事件相关说明文档仓库 docs/erp-stock.md开源协议标注为 Apache 2.0协议内明确规定了源码使用约束可供技术学习参考。