#laravel #eloquent #transactions
#laravel #красноречивый #транзакции
Вопрос:
У меня есть модель, Agent
и у нее много agent accounts
.
public function agentAccounts(): Relation
{
return $this->hasMany(AgentAccount::class);
}
Я хочу удалить их за одну транзакцию, но используя boot
метод
public static function boot()
{
parent::boot();
self::deleting([self::class, 'onDeleting']);
}
Я понимаю, что когда я создаю транзакцию БД внутри функции «onDeleting», подобной этой
public static function onDeleting(self $model): void
{
DB::transaction(function () use ($model) {
$agentAccounts = $model->agentAccounts;
foreach ($agentAccounts as $agentAccount) {
/* @var $agentAccount AgentAccount */
$agentAccount->delete();
}
}, 5);
}
Транзакция db не включает удаление самого агента.
Это предшествует транзакции db по удалению агента.
В моем случае удаление агента может завершиться неудачей из-за некоторых ограничений уровня SQL, не связанных с учетными записями агентов
и если я использую приведенный выше пример, я могу в конечном итоге удалить все учетные записи агентов, но сохранить агент.
Я не хочу, чтобы это произошло.
Я хочу, чтобы они либо удалялись вместе, либо сохранялись вместе.
Как я могу это сделать?
Комментарии:
1. Я не верю, что это будет возможно с событиями модели, если вы не перезапишете исходные методы eloquent, по какой-либо причине вы не хотите использовать
->onDelete('cascade')
дляAgentAccount
внешнего ключаAgent
? Таким образом, он автоматически удалит все учетные записи, если агент будет успешно удален.2. Спасибо. «каскад» не настолько гибкий, я упростил вопрос. На самом деле есть условия и задействовано больше таблиц.
Ответ №1:
Я считаю, что события DB выполняются в режиме блокировки, поэтому при вызове delete()
модели достаточно сделать это внутри транзакции, вот так
DB::transaction(function () use($user) { $user->delete(); });