2017-06-19 138 views
0

遇到作業無法連接到數據庫的問題。Laravel多租戶作業

Invalid catalog name: 1046 No database selected

我需要設置帳戶的工作,所以我有一個擴展的類,以確保該帳戶與作業一起發送,這樣我可以確保數據庫能夠連接到正確的數據庫。

<?php 

namespace App\Jobs; 

use Illuminate\Support\Facades\DB; 

abstract class Job 
{ 
    protected $account; 

    public function start() 
    { 
     // runs when creating the job, so the config holds the correct value 
     $this->account = config('database.connections.tenant.database'); 
    } 

    public function handle() 
    { 
     // since the handle function runs outside of setting the job 
     // the database is no longer set in the config 
     config()->set('database.connections.tenant.database', $this->account); 
     // try to force it to reconnect incase it already did for some reason. 
     DB::reconnect(); 
    } 
} 

這是我現在玩的版本,變化似乎不會影響它。我基本上在構造函數中運行start,然後確保它在作業中運行父項handle,以便引導適當的db配置。

我在尋找的最終結果是將租戶數據庫設置爲account,並在其運行作業時使用該數據庫進行所有查詢。

回答

0

找到了解決方法。它不漂亮,但基於我可以看到的是,拉拉隊隊列並不能很好地處理這種事情。

首先,我刪除了handle函數的覆蓋,我真正需要的是確保需要運行的隊列在Job類上可用。

abstract class Job 
{ 
    protected $account; 

    public function start() 
    { 
     // runs when creating the job, so the config holds the correct value 
     $this->account = config('database.connections.tenant.database'); 
    } 
} 

接着我在boot方法移動的開關到正確的租戶數據庫到AppServiceProvider

Event::listen(JobProcessing::class, function ($event) { 
    if ($payload = $event->job->payload()) { 
     preg_match('/"account";s:[0-9]+:"(.*?)"/', $payload['data']['command'], $matches); 
     if (count($matches)) { 
     if (isset($matches[1])) { 
      config()->set('database.connections.tenant.database', $matches[1]); 
      config()->set('database.default', 'tenant'); 
     } 
     } 
    } 
}); 

我在這裏做的是用一些正則表達式來查看賬戶的序列化對象。可能會在這裏做出改進,但迄今爲止在測試中起作用。然後在確認帳戶後設置正確的數據庫。

我不得不這樣做的原因是,當作業本身被序列化時,作業會進行查詢,所以爲了傳遞它的序列化之前需要完成的帳戶。