从其他控制器调用的laravel事务

时间:2015-01-29 06:16:51

标签: laravel transactions

如果我的BaseController中有一个函数,那里有像这样的事务

public static function add_lead_logs($lead_id, $module, $action)
{
    DB::beginTransaction();

    $lead_log               = new LeadLogsModel();
    $lead_log->lead_id  = $lead_id;
    $lead_log->create_by    = Session::get('SESS_USER_ID');
    $lead_log->module       = $module;
    $lead_log->action       = $action;
    if(!$lead_log->save())
    {
        DB::rollback();

        return false;
    }
    else
    {
        DB::commit();

        return true;
    }
}

然后我在控制器中调用该函数,假设我正在更新某些内容

DB::beginTransasction()

$lead = LeadModel::find(1);
$lead->status = '1';
if($lead->save())
{
   if($this->add_lead_logs($id,$module,$action))
   {
        DB::commit();
   }
}
else
{
   DB::rollback();
}

我怎么才能有一笔交易?我不确定在出现错误时是否会成功回滚。

1 个答案:

答案 0 :(得分:3)

Laravel通过事务计数器支持嵌套事务。 DB::beginTransasction()递增计数器,DB::commit()DB::rollback()递减计数器。

实际的数据库提交/回滚操作仅发生在最外层的事务调用上。如果您要手动调用DB::beginTransasction()DB::commit()DB::rollback()方法,则需要确保始终将它们配对。

对于当前代码,如果$lead->save()返回true,但$this->add_lead_logs()返回false,则您将输入一个不会在最外层事务上调用commit / rollback的代码路径。您需要在其他条件下添加回滚。

if($lead->save()) {
    if($this->add_lead_logs($id,$module,$action)) {
        DB::commit();
    } else {
        // make sure to rollback if add_lead_logs failed
        DB::rollback();
    }
} else {
    DB::rollback();
}

这将确保对于所有代码路径,将始终提交或回滚事务。