使用 Laravel 5.1 跨多个 Eloquent 模型进行交易

Transaction across multiple Eloquent Models using Laravel 5.1

我想将一个 parent 项及其所有子项插入数据库。如果有任何孩子创建失败,我想中止整个交易。

我试过使用以下代码段:

DB::beginTransaction();

try
{
    // Create parent item
    $one = new ModelOne();
    $one->key = 'Parent Key';
    $one->title = 'Parent title';
    $one->save();

    // Create child items
    foreach ($items as $item) {
        $two = new ModelTwo();
        $two->parent_id = $one->id;
        $two->content = $item->content;
        $two->status = $item->status;
        $two->save();
    }

    DB::commit();
    return response(['message'=>'ALL GOOD'], 200);
}
catch (\ Illuminate\Database\QueryException $e)
{
    DB::rollBack();
    return response(['message'=>'FAILURE'], 500);
}

然而,当抛出异常时(比如因为一个键在孩子之间重复)即使 DB::commit() 从未被调用,ModelOne$one)也会保存在数据库中.

我错过了什么?

我正在使用 Laravel 5.1。

我使用此代码进行交易并且有效:

DB::transaction(function () { 
});

使用此代码,您无需提交或回滚。它们被自动调用。

在您的情况下,您将拥有:

try {
    DB::transaction(function () use ($items) ({ 
        // ... your inserts
    });
catch () {}

原来这个问题与我在问题中提供的代码无关。

问题是我的表是使用 MyISAM 创建的,其中 does not support transactions

改为使用 InnoDB 可使代码按预期工作。为此,请将 $table->engine = 'InnoDB'; 添加到您的迁移中。