如果我的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();
}
我怎么才能有一笔交易?我不确定在出现错误时是否会成功回滚。
答案 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();
}
这将确保对于所有代码路径,将始终提交或回滚事务。