You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于order_stock表扣减stock_incoming表库存的MySQL逻辑问题排查

问题根因

你当前的代码仅完成了「订单与物料的关联绑定」操作,全程没有对stock_incoming库存表执行任何更新动作,自然无法实现库存扣减。除此之外,你的逻辑还缺少2个必要的校验环节:

  • 扣减前未校验stock_incoming表对应物料的剩余库存是否足够覆盖本次下单数量,会出现负库存异常
  • 未开启事务保证「关联订单物料」和「扣减库存」两个操作的原子性,一旦其中一个步骤失败会出现数据不一致

调整方案

代码改造示例

你使用的是Laravel+Livewire技术栈,调整后的save方法逻辑如下:

public Order $order;
public $selectedMat;

public function save()
{
    // 开启事务保证操作原子性
    \DB::beginTransaction();
    try {
        foreach ($this->selectedMat as $value) {
            // 按选中的stock_incoming id查询库存记录,高并发场景下可加lockForUpdate()行锁避免超卖
            $stockIn = \App\Models\StockIncoming::where('id', $value['stock_in_id'])->lockForUpdate()->firstOrFail();
            // 校验库存是否足够
            if ($stockIn->remaining_qty < $value['qty']) {
                throw new \Exception("物料ID:{$value['id']} 库存不足,剩余{$stockIn->remaining_qty},需扣减{$value['qty']}");
            }
            // 执行库存扣减
            $stockIn->decrement('remaining_qty', $value['qty']);
            // 关联订单物料,建议冗余存储扣减的入库单ID方便后续对账
            $this->order->materials()->attach([$value['id'] => [
                'qty' => $value['qty'],
                'stock_in_id' => $value['stock_in_id']
            ]]);
        }
        $this->order->refresh();
        \DB::commit();
        $this->emit('parent-refresh');
        $this->emit('closeModal', 'matmodal');
    } catch (\Exception $e) {
        \DB::rollBack();
        // 可在此处增加前端错误提示逻辑
        throw $e;
    }
}

配套调整说明

  • 确认前端传递的selectedMat数组中已经包含选中的stock_in_id参数,对应stock_incoming表的主键ID
  • 建议给order_stock表增加stock_in_id字段,用于关联本次扣减的入库记录,方便后续库存对账、退库等操作

内容的提问来源于stack exchange,提问作者HitoriDev

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.26 19:36:01