Транзакция laravel вызывается с других контроллеров
Если у меня будет функция в моем 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 транзакцию? Я не уверен, удастся ли выполнить откат успешно при возникновении ошибки.
1 ответ
Laravel поддерживает вложенные транзакции через счетчик транзакций. DB::beginTransasction()
увеличивает счетчик и DB::commit()
а также DB::rollback()
уменьшить счетчик.
Фактические действия фиксации / отката базы данных происходят только при самом внешнем вызове транзакции. Если вы собираетесь вручную позвонить DB::beginTransasction()
, DB::commit()
, а также DB::rollback()
методы, то вам нужно убедиться, что вы всегда их сопрягаете.
В случае вашего текущего кода, если $lead->save()
возвращает истину, но $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();
}
Это гарантирует, что для всех путей кода транзакция всегда будет зафиксирована или откатана.