DB::transaction() 可以将 Eloquent 查询作为事务执行吗?

Can DB::transaction() execute Eloquent queries as transaction?

我:这是一个混合问题 | 访客:(wtf?)这是什么意思?

我在一个问题中问 2 个问题(因为它紧密耦合)

使用:Laravel 5.5 & Mysql

1。如何删除eloquent中的相关模型?

我正在尝试删除具有以下关系的User

属于Address, 属于 Package, 有很多 Orders, 有很多 Comments

OrdersUserProduct 被删除时级联 COmmentsUserPost 被删除时级联。

现在如何删除 User 并自动删除关联的 orderscomments

当我尝试使用 $user->delete() 删除时 laravel 抛出异常:

SQLSTATE[23000]: Integrity constraint violation: 1451 Cannot delete or update a parent row: a foreign key constraint fails (`cybertron`.`comments`, CONSTRAINT `comments_user_id_foreign` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`)) (SQL: delete from `users` where `id` = 4)

所以我决定使用事务来删除用户、关联的订单和评论, 确保所有内容都被删除。

但是我没有在 eloquent 中找到任何交易,而是在查询生成器 (DB) 中。

2。如果我使用数据库中的事务并使用 eloquent 删除用户 ($user->delete),这会被视为事务吗?

喜欢:

DB::transaction(function() {

      $user->comments->delete();
      $user->orders->delete();
      $user->delete();
});

如果没有,我如何与 Eloquent 进行交易?

任何帮助将不胜感激

  1. 您有 Eloquent events 用于删除,但您也可以覆盖默认删除方法,如下所示:

    public function delete()
    {
        \DB::transaction(function() {
            $this->comments()->delete();
            $this->orders()->delete();
            parent::delete(); 
         });
    }
    
  2. 是的,Eloquent本身没有交易。您使用显示的事务并将 Eloquent 或查询构建器包装在其中。请注意,在您的情况下,您应该使用 comments()orders() 而不是 commentsorders

@Marcin

如果您在模型上使用事件,为了级联删除,您需要确保您了解查询对象上的 运行ning 删除与模型上的 运行ning 删除之间的区别对象

例如: $this->orders()->delete(); - 这一行实际上并没有加载订单模型 - $this->orders() - returns 一个查询对象 - 这一行实际上 运行 一个 DELETE SQL 语句

为了在删除用户时按顺序启动删除事件,您必须执行 foreach foreach($user->orders as $order) $order->delete();

当user::deleting事件启动时,加载用户所有订单并调用delete; 这将触发 order::deleting 事件,我们将在其中加载所有评论对象并删除它们