Laravel排队作业如何处理已删除的模型作为输入



如果Laravel排队的作业作为输入传递了Eloquent 模型,但在队列中运行作业之前删除了模型,会发生什么情况?

例如,我正在使用Laravel 5.2构建一个电子商务网站,客户可以在其中输入地址和付款方式。付款方式属于地址。但是,如果客户尝试删除地址,而不是级联并删除与之关联的任何付款方式,我会通过将地址标记为禁用来软删除该地址。这样,付款方式仍然可以使用,直到客户更新与其关联的帐单邮寄地址。

但是,如果删除了付款方式,并且它引用了已软删除的地址,则我想进行一些垃圾回收并从数据库中删除该地址。这不需要同步发生,所以我编写了一个简单的可排队作业来完成此操作。句柄方法如下所示:

public function handle(PaymentMethodRepository $paymentMethodRepository, AddressRepository $addressRepository)
{
    $billingAddress = $paymentMethodRepository->address($this->paymentMethod);
    if ( ! $billingAddress->enabled) {
        $addressRepository->delete($billingAddress);
    }
}

我以支付方法控制器的destroy方法调度此作业。但是,如果在队列中执行作业之前从数据库中删除传递给作业的付款方式,作业是否会失败?

我仍在开发网站,所以我没有服务器来部署和测试会发生什么。我知道模型被序列化以放入队列中,但我想知道在恢复模型以执行作业时是否会出现问题。

是的

,如果在执行作业之前删除了"序列化模型",则作业将失败。模型并没有真正序列化 - 作业存储模型类和模型标识符,并在执行之前获取模型。

要解决此问题,您可以将模型的主键存储在作业中,然后在执行作业时检查记录是否存在:

class DeleteAddressJob extends Job implements ShouldQueue
{
    private $addressId;
    public function __construct(int $addressId)
    {
        $this->addressId = $addressId;
    }
    public function handle(AddressRepository $addressRepository)
    {
        $address = $addressRepository->find($this->addressId);
        if (is_null($address)) {
            // Address doesn't exist. Complete job...
            return;
        }
        // Delete the address...
    }
}

最新更新