实战来了,基于DDD实现库存扣减~

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

@RestController
@Tag(name = "InventoryController", description = "库存API接口")
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
@Slf4j
public class InventoryController {
 ...
 
    @Operation(summary = "库存预扣",description = "sq-,wq+,创建订单时调用")
    @PostMapping("/api/inventory/withholdInventory")
    public void withholdInventory(@Valid @RequestBody InventoryLockRequest lockRequest)  {
        inventoryService.withholdInventory(lockRequest);
    }

    @Operation(summary = "库存扣减",description = "wq-,oq+,付款时调用")
    @PutMapping("/api/inventory/deductionInventory")
    public void deductionInventory(@RequestParam("transactionId") Long transactionId)  {
        inventoryService.deductionInventory(transactionId);
    }

    @Operation(summary = "库存发货",description = "oq-,发货时调用")
    @PutMapping("/api/inventory/shipInventory")
    public void shipInventory(@RequestParam("transactionId") Long transactionId)  {
        inventoryService.shipInventory(transactionId);
    }

    @Operation(summary = "释放库存")
    @PutMapping("/api/inventory/releaseInventory")
    public void releaseInventory(@RequestParam("transactionId") Long transactionId)  {
        inventoryService.releaseInventory(transactionId);
    }
    ...
}

在这里插入图片描述

@Service
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
@Slf4j
public class InventoryServiceImpl implements InventoryService {    
    ...
    @Override
    @Transactional
    public void withholdInventory(InventoryLockRequest inventoryLockRequest) {
        Long inventoryId = inventoryLockRequest.getInventoryId();
        //1. 获取库存
        Inventory inventory = Optional.ofNullable(inventoryRepository.find(new InventoryId(inventoryId)))
                .orElseThrow(()->new BusinessException("No inventory found with id:" + inventoryId));

        // 2. 幂等校验
        boolean exists = inventoryRepository.existsWithTransactionId(inventoryLockRequest.getTransactionId());

        if(exists ){
            log.error("Inventory record with transaction ID {} already exists, no deduction will be made.", inventoryLockRequest.getTransactionId());
            return;
        }

        //3. 库存预扣
        inventory.withholdInventory(inventoryLockRequest.getQuantity());

        //4. 生成扣减记录
        InventoryRecord inventoryRecord = InventoryRecord.builder()
                .inventoryId(inventoryId)
                .userId(inventoryLockRequest.getUserId())
                .deductionQuantity(inventoryLockRequest.getQuantity())
                .transactionId(inventoryLockRequest.getTransactionId())
                .state(InventoryRecordStateEnum.PRE_DEDUCTION.code())
                .build();

        inventory.addInventoryRecord(inventoryRecord);

        inventoryRepository.save(inventory);
    }
    ...
}

在这里插入图片描述

@Data
public class Inventory implements Aggregate<InventoryId> {
    @Serial
    private static final long serialVersionUID = 2139884371907883203L;
    private InventoryId id;
 
 ...

    /**
     * 库存预扣 sq-,wq+
     * @param quantity  数量
     */
    public void withholdInventory(int quantity){
        if (quantity <= 0) {
            throw new BusinessException("扣减库存数量必须大于零");
        }

        if (getInventoryQuantity() - quantity < 0) {
            throw new BusinessException("库存不足,无法扣减库存");
        }

        sellableQuantity -= quantity;
        withholdingQuantity += quantity;
    }
  
    /**
     * 释放库存
     * @param currentState 当前状态
     * @param quantity 数量
     */
    public void releaseInventory(int currentState, Integer quantity) {
        InventoryRecordStateEnum stateEnum = InventoryRecordStateEnum.of(currentState);
        switch (stateEnum){
            //sq+,wq-
            case PRE_DEDUCTION -> {
                sellableQuantity += quantity;
                withholdingQuantity -= quantity;
            }
            //sq+,oq-
            case DEDUCTION -> {
                sellableQuantity += quantity;
                occupyQuantity -= quantity;
            }
            //sq+
            case SHIPPED -> {
                sellableQuantity += quantity;
            }
        }
    }
 ...
}

/**
* 仓储接口定义
*/
public interface InventoryRepository extends Repository<Inventory, InventoryId> {
    boolean existsWithTransactionId(Long transactionId);

    Inventory findByTransactionId(Long transactionId);
}

在这里插入图片描述

@Repository
@Slf4j
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class InventoryRepositoryImpl implements InventoryRepository {
    ...
    @Override
    public Inventory find(InventoryId inventoryId) {

        InventoryItemDO inventoryItemDO = inventoryItemMapper.selectById(inventoryId.getValue());
        return itemInventoryConverter.fromData(inventoryItemDO);
    }

    @Override
    public Inventory save(Inventory aggregate) {
        InventoryItemDO inventoryItemDO = itemInventoryConverter.toData(aggregate);

        if(inventoryItemDO.getId() == null){
            inventoryItemMapper.insert(inventoryItemDO);
        }else{
            inventoryItemMapper.updateById(inventoryItemDO);
        }

        InventoryRecord inventoryRecord = aggregate.getInventoryRecordList().get(0);
        InventoryRecordDO inventoryRecordDO = inventoryRecordConverter.toData(inventoryRecord);

        if(inventoryRecordDO.getId() == null){
            inventoryRecordMapper.insert(inventoryRecordDO);
        }else{
            inventoryRecordMapper.updateById(inventoryRecordDO);
        }

        return aggregate;
    }
    ...
}

在这里插入图片描述

转载:https://mp.weixin.qq.com/s?__biz=MzAwMTk4NjM1MA==&mid=2247517846&idx=1&sn=9e06785056234fc1b208912efe041f5c&chksm=9ad39cd7ada415c1f0f165880a8f8d0125dfcd271ccb0538da1333c55aada4d6a3e2f122abec&scene=132&exptype=timeline_recommend_article_extendread_samebiz#wechat_redirect

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 抱歉,我是AI语言模型,无法提供下载链接。但是,中台架构是一种基于DDD和微服务的架构模式,旨在实现业务的模块化、可复用、可扩展和可维护性。该架构模式可以帮助企业实现业务的快速迭代和创新,提高业务的灵活性和可靠性。如果您对该架构模式感兴趣,可以通过搜索引擎查找相关资料进行学习和了解。 ### 回答2: 中台架构是一种适用于大型企业的架构模式,它通过将企业的业务逻辑进行抽象和标准化,以横向的形式实现了业务功能的复用和共享,提升了企业的业务流程整合和数据信息共享的能力,从而提高了企业的业务灵活性、扩展性和可维护性。 基于领域驱动设计(DDD)和微服务(Microservice),中台架构能够更好地实现业务逻辑的拆解和整合。DDD是一种将业务需求转化为可编程软件的模式,通过定义领域、业务模型和领域逻辑等方式实现将复杂业务流程进行简化;而微服务是一种以服务拆分为基础的架构模型,通过将业务逻辑进行拆解和分离,以模块化的形式实现微服务的组装和组合。 中台架构的实现可以从以下几个方面入手: 首先,应该根据业务领域进行领域划分和业务建模。通过将复杂的业务流程拆解为多个业务模块,根据业务领域设计相应的领域模型和领域逻辑,并将其实现为独立的微服务。 其次,要实现模块化的微服务。将独立的业务模块进行拆解和分离,以微服务的形式进行实现,并将其注册到服务发现机制中。在运行时,根据服务发现机制能够获取和组合所需要的微服务,从而实现对业务逻辑的调用和组合。 最后,应该通过组合多个微服务实现业务流程。将多个微服务进行组合、串联调用,通过对数据进行传递和处理,最终实现用户所需要的功能。通过这种方式,可以实现业务流程的合理化、优化和标准化。同时,中台架构还能够提供业务流程监控、数据收集等功能,实现对业务流程全面、深度的控制和分析。 总之,中台架构及其基于DDD和微服务的实现方案不仅提升了企业的业务流程和数据信息共享能力,还提高了业务灵活性、扩展性和可维护性。它是一种强大的架构模型,值得企业进行思考和应用。 ### 回答3: 中台架构是一种基于业务场景的架构模式,通过将不同业务场景进行拆分和归类,建立中台(业务中枢),实现业务的复用和快速响应。基于DDD(领域驱动设计)和微服务的实现可以更好地支持中台架构。 中台架构基于业务能力进行划分,每个业务能力都有自己的领域模型和业务逻辑。而DDD则是一种通过领域模型来实现业务逻辑的设计思想。通过结合中台架构和DDD,可以更好地将业务逻辑与技术逻辑分离,实现业务代码的可读性和可维护性。 微服务则是指将一个大型的应用拆分成多个互相独立的小应用来实现,每个小应用专注于某个业务领域的处理。这种拆分方式可以使得应用更加灵活,更容易实现弹性伸缩和快速迭代。而基于微服务的实现方式则是将每个业务域都拆分成单独的微服务,实现服务之间的高度解耦和快速响应。 在中台架构实现中,将不同业务场景进行拆分和归类,建立中台(业务中枢),可以实现代码的复用和快速响应。而基于DDD和微服务的实现方式,则是将代码进一步拆分,每个业务领域都独立成为一个微服务,并通过领域模型来实现业务逻辑,从而实现更好的可读性和可维护性。 总之,中台架构和DDD和微服务的实现方式,可以更好地支持业务拆分和技术解耦,实现业务的复用和快速响应,是一种适合大型企业的架构模式,可以提高企业的业务效率和快速响应能力。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值