乐观锁库存冻结操作

[复制链接]
发表于 10 小时前 | 显示全部楼层 |阅读模式

代码分析:乐观锁库存冻结操作

基于 MyBatisDisposeUtil.java 的分析,这段代码实现了带乐观锁的库存冻结功能

核心功能

这是一个**库存预留(冻结)**操作,用于在业务订单处理时锁定一定数量的库存,防止超卖。

方法参数解析

参数 作用
oriStock 原始库存对象(首次尝试使用)
第1个Lambda 从数据库获取最新库存数据(重试时使用)
第2个Lambda 核心业务逻辑:校验库存→扣减可用库存→增加冻结库存→创建冻结记录
第3个Lambda 失败时生成异常信息

业务逻辑流程

  1. 库存校验:检查可用库存是否充足(availableQty >= freezeQty
  2. 库存调整
    • 可用库存减少:availableQty - freezeQty
    • 冻结库存增加:frozenQty + freezeQty
  3. 创建冻结记录:插入 StoreStockFrozen 记录,包含:
    • 冻结数量、类型、原因
    • 关联的订单信息(订单号、明细ID等)
  4. 更新库存:持久化修改后的库存数据

乐观锁机制

首次尝试 → 使用原始数据
    ↓ 失败(版本号冲突)
重试(最多10次) → 新开事务获取最新数据 → 执行业务逻辑
    ↓ 成功
返回
    ↓ 全部失败
抛出异常
  • 最大重试次数:10次
  • 重试间隔:1000ms
  • 事务策略REQUIRES_NEW 确保每次重试都是独立事务

异常处理

当所有重试都失败时,抛出包含件号(PN)、序号(SN)、标签号的详细错误信息,便于定位问题。

总结

这段代码通过乐观锁+自动重试机制,确保在高并发场景下库存扣减的准确性和数据一致性,是电商/仓储系统中常见的库存防超卖解决方案。


myBatisDisposeUtil.execOptimisticLockFn(oriStock,() -> {
return getById(stockDto.getPkid());
}, (dto) -> {
if (dto == null){
dto = byId;
}
if (dto.getAvailableQty().compareTo(freezeQty) < 0) {
throw new BusinessException(StorageResultCode.STORAGE_FREEZE_QTY1);
}
dto.setAvailableQty(dto.getAvailableQty().subtract(freezeQty));
dto.setFrozenQty(dto.getFrozenQty().add(freezeQty));

StoreStockFrozen frozen = new StoreStockFrozen();
        frozen.setStoreStockPkid(dto.getPkid());
         
        storeStockFrozenService.insertSelectiveWithLoginUser(frozen, userInfo);
        return updateByPrimaryWithLoginUser(dto, userInfo) > 0;
    }, (dto) -> {
        if (ObjectUtil.isNull(dto)) {
            return new BusinessException(500, "操作失败, 处理库存失败!");
        }
        return new BusinessException(500, StrUtil.format("操作失败, 件{},{} {} 处理库存错误!", dto.getPn(), StrUtil.emptyIfNull(dto.getSn()), dto.getTagNo()));
    });

GMT+8, 2026-5-11 20:12 , Processed in 0.079669 second(s), 34 queries Archiver|手机版|小黑屋|Attic ( 京ICP备2020048627号 )

快速回复 返回顶部 返回列表