首页 > 解决方案 > 如何仅在多租户项目的主数据库中执行作业?

问题描述

我有一个项目,当我的用户注册时,我的项目默认连接到我的主数据库公共模式。

当用户成功注册时,我会发起一个发送电子邮件的事件,这是我的事件监听器:

class WelcomeNewCompanyListener implements ShouldQueue
{
    /**
     * Create the event listener.
     *
     * @return void
     */
    public function __construct()
    {
        //
    }

    /**
     * Handle the event.
     *
     * @param  object  $event
     * @return void
     */
    public function handle($event)
    {

        $data = array (
            'name' =>  $event->company['name'],
            'email' =>  $event->company['email'],
        );

        $beautymail = app()->make(\Snowfire\Beautymail\Beautymail::class);
        $beautymail->send('emails.welcome', $data, function($message) use ($data)
        {
            $message
                ->from('contato@44online.com.br', '44 Online')
                ->to($data['email'], $data['name'])
                ->subject('Bem vindo a 44 Online!');
        });
    }
}

当我使用与公共相同的架构时它工作正常,但是如果我提出需要更改租户架构的请求并且用户根据示例进行 ResetPasswordEvent。

我的项目在这里更改了中间件中的连接:

 public function reconnect($companyInfo) {    

      DB::purge('tenant');
      Config::set('database.connections.tenant.schema', $companyInfo[0]->db_schema);
      DB::reconnect('tenant'); 
      Schema::connection('tenant')->getConnection()->reconnect();

   }

问题是当用户创建一个 ResetPasswordEvent 我的项目工作,但他正在从租户的数据库上制作,而不是主表我尝试在句柄之后重新连接但不工作,它坚持插入租户在数据库中的作业。我应该怎么办?

当我在句柄上建立这个连接时

      DB::purge('tenant');
      Config::set('database.connections.tenant.schema', 'public');
      DB::reconnect('tenant'); 
      Schema::connection('tenant')->getConnection()->reconnect();

我得到这个失败的工作,我不使用任何连接

PDOException: SQLSTATE[42P01]: Undefined table: 7 ERROR:  relation "qu_users" does not exist
LINE 1: select * from "qu_users" where "qu_users"."users_id" is null...
                      ^ in 

怎么了?

标签: laravelqueuejobs

解决方案


由于作业可能/应该在另一个进程中运行,因此更改默认驱动程序会丢失(无论如何这对我来说似乎不是一个好主意)

但无论如何,如果您希望您的工作使用不同的数据库。在句柄中,您需要将作业的构造函数传递给它。例如 new Job('tenant') / App::make(MyJob::class, ['connectionName' => 'tenant']);

这样在handle()中应该可以得到连接名,进入handle()函数后就可以改变连接了。

它一开始就需要主连接,因为您的队列工作人员可能无论如何都在该连接上运行。


推荐阅读