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

Laravel事务报错后数据未回滚问题及原因解析

Laravel事务未回滚+「No morph map defined for model [App\Models\Order]」问题排查与解决

问题现象

  • 采用两种Laravel事务写法(手动事务、闭包事务)执行时,均抛出No morph map defined for model [App\Models\Order]错误
  • 错误触发后,Order::create()生成的数据并未被回滚,仍保留在数据库中

代码示例

1. 手动事务写法

\DB::beginTransaction();

try {
    $order = Order::create([
        // 数据内容
    ]);

    $order->notes()->create([
        // 数据内容,此处会引发错误
    ]);

    // 抛出错误:No morph map defined for model [App\Models\Order].
    $order->transaction()->create([
        // 数据内容
    ]);

} catch (\Exception $e) {
    \DB::rollBack();
    return "error";
}

\DB::commit();

return "success";

2. 闭包事务写法

\DB::transaction(function() use ($offer, $request) {
    $buyer = auth()->user();

    $order = Order::create([
        // 数据内容
    ]);

    $order->notes()->create([
        // 数据内容
    ]);

    // 抛出错误:No morph map defined for model [App\Models\Order](因未定义模型别名)
    $order->transaction()->create([
        // 数据内容
    ]);
});

return "success";

问题根源

  1. 事务无法回滚原因:Laravel默认数据库引擎配置为空,当前使用的是不支持事务的MyISAM引擎——MyISAM本身不支持事务机制,因此即便调用rollBack(),已写入的数据也无法撤销。
  2. 多态关联错误原因:多态关联未定义模型别名,导致框架无法识别App\Models\Order对应的多态类型标识。

解决步骤

1. 切换数据库引擎为InnoDB

  • 修改config/database.php中对应数据库连接的配置,指定引擎为InnoDB:
    'mysql' => [
        // 其他配置项
        'engine' => 'InnoDB',
    ],
    
  • 对已存在的表手动修改引擎:
    ALTER TABLE orders ENGINE=InnoDB;
    ALTER TABLE notes ENGINE=InnoDB;
    ALTER TABLE transactions ENGINE=InnoDB; -- 对应transaction关联的表
    

2. 配置多态模型映射

在App\Providers\AppServiceProvider的boot()方法中添加多态映射,解决模型别名缺失问题:

use Illuminate\Database\Eloquent\Relations\Relation;

public function boot()
{
    Relation::morphMap([
        'order' => \App\Models\Order::class,
        // 可添加其他多态模型的映射关系
    ]);
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 08:57:32