如果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...
}
}