如果抛出异常,Laravel数据库事务会发生什么?

tim*_*der 4 php mysql laravel laravel-5

我认为*交易刚被丢弃.这准确吗?

我正在使用mysql

例:

try {
    DB::beginTransaction();
    throw new Exception("something happened");
    DB::commit()
} catch (Exception $e) {
    Log::debug("something bad happened");
}
Run Code Online (Sandbox Code Playgroud)

谢谢

Dev*_*von 5

未提交的事务将在 SQL 中被丢弃。

当你在这里抛出异常时,DB::commit()永远不会到达。您将直接进入 catch() 块,因此交易将被丢弃(只要DB::commit()稍后没有在某个地方调用)。

但是,如果您不想在引发异常时提交事务,我仍然建议在 catch 块中显式回滚事务,这将关闭该事务并防止对该执行中的未来查询产生任何影响。

try {
    DB::beginTransaction();
    throw new Exception("something happened");
    DB::commit()
} catch (Exception $e) {
    Log::debug("something bad happened");
    DB::rollBack();
}
Run Code Online (Sandbox Code Playgroud)

或者使用带有闭包的内置 DB::transaction() 来在未捕获异常时自动回滚,记录如下: https: //laravel.com/docs/5.3/database#database-transactions


Fel*_*rte 5

如果您在Closure中使用,例如:

DB::transaction(function () {
    DB::table('users')->update(['votes' => 1]);
    DB::table('posts')->delete();
});
Run Code Online (Sandbox Code Playgroud)

您将在框架内运行此代码:

public function transaction(Closure $callback)
{
    $this->beginTransaction();

    // We'll simply execute the given callback within a try / catch block
    // and if we catch any exception we can rollback the transaction
    // so that none of the changes are persisted to the database.
    try {
        $result = $callback($this);

        $this->commit();
    }

    // If we catch an exception, we will roll back so nothing gets messed
    // up in the database. Then we'll re-throw the exception so it can
    // be handled how the developer sees fit for their applications.
    catch (Exception $e) {
        $this->rollBack();

        throw $e;
    } catch (Throwable $e) {
        $this->rollBack();

        throw $e;
    }

    return $result;
}
Run Code Online (Sandbox Code Playgroud)

因此,在这种情况下,您100%确定事务将要回滚.如果您手动打开事务处理DB::beginTransaction();,则无法确定是否要回滚,除非您确保使用以下内容:

try {
    DB::beginTransaction();
    //do something
    DB::commit();
} catch (\Exception $e) {
    DB::rollback();
}
Run Code Online (Sandbox Code Playgroud)

如果你抛出一个没有catch的异常,脚本死掉或以打开的事务结束,PDO将自动回滚(http://php.net/manual/en/pdo.transactions.php):

当脚本结束或即将关闭连接时,如果您有未完成的事务,PDO将自动回滚.