2016-02-13 61 views
1

如果Laravel隊列作業作爲輸入傳遞一個Eloquent模型會發生什麼情況,但是該作業在隊列中運行之前將刪除該模型?Laravel排隊作業如何處理刪除的模型作爲輸入?

例如,我正在用Laravel 5.2構建一個電子商務網站,客戶可以在其中輸入地址和付款方式。付款方式屬於地址。但是,如果客戶試圖刪除地址,而不是級聯並刪除與其關聯的任何付款方式,我會通過將其標記爲已禁用來軟刪除地址。這樣,付款方式仍然可以使用,直到客戶更新與其關聯的帳單地址。

但是,如果付款方法被刪除,並且它引用了一個已被軟刪除的地址,我想要做一些垃圾收集並從數據庫中刪除地址。這不需要同步發生,所以我寫了一個簡單的隊列工作來完成這個任務。手柄的方法是這樣的:

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

    if (! $billingAddress->enabled) { 
     $addressRepository->delete($billingAddress); 
    } 
} 

我派遣在PaymentMethodsController的destroy方法這項工作。但是,如果在作業在隊列中執行之前將傳遞給作業的付款方式從數據庫中刪除,作業是否會失敗?

我仍在開發該網站,所以我沒有服務器來部署和測試會發生什麼。我知道模型被序列化爲隊列,但是我想知道當模型恢復執行作業時是否會發生問題。

回答

0

是的,如果在作業執行前刪除了「序列化模型」,作業將會失敗。模型沒有真正序列化 - 作業存儲模型類和模型標識符,並在執行之前獲取模型。

要解決這個問題,你可以存儲模型的主鍵的作業,然後在執行任務時,請檢查是否存在記錄:

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