我正在使用Laravel 5
与php 5.5.9-1ubuntu4.14
和mysql 5.5.47
。
我有一个多租户环境,每个租户都有一个单独的数据库。因此,对于每个HTTP请求,我都在BeforeMiddleware
中设置适当的数据库连接,如此
public function handle($request, Closure $next)
{
...
// Set the client DB name and fire it up as the new default DB connection
Config::set('database.connections.mysql_client.host', $db_host);
Config::set('database.connections.mysql_client.database', $db_database);
Config::set('database.connections.mysql_client.username', $db_username);
Config::set('database.connections.mysql_client.password', $db_password);
DB::setDefaultConnection('mysql_client');
...
}
即使对于并发HTTP请求,这也能正常工作。
但现在我想将预定作业添加到我的应用程序中。这些作业将向属于所有租户的用户发送通知。所以,我再次需要连接到各自的租户数据库。但是这种连接不会通过HTTP请求。假设我有一个CommunicationController
和一个用于发送通知的函数。
public function sendNotification()
{
...
DB::purge('mysql_client');//IMP
// Set the client DB name and fire it up as the new default DB connection
Config::set('database.connections.mysql_client.host', $db_host);
Config::set('database.connections.mysql_client.database', $db_database);
Config::set('database.connections.mysql_client.username', $db_username);
Config::set('database.connections.mysql_client.password', $db_password);
DB::setDefaultConnection('mysql_client');
...
}
这是我设置Config
值的地方。此功能将通过Laravel Scheduler
每分钟执行一次。
我的问题是:
Config
参数都在HTTP请求和预定作业中设置?答案 0 :(得分:5)
根据Laravel docs:
仅在运行时设置的配置值 当前请求,不会转发给后续请求。
当您专门调用proj1
方法时,配置值在运行时设置,因此该值仅对该当前请求有效,并且您将永远不会出现任何并发问题。
你的第二个问题也是不可能的。即使您以前的任务在数据库上运行请求,第二个/后续任务也会等待锁定(如果要在数据库上发布)。您应该尝试通过使用multi-insert,sqldump(如果您正在执行大型查询)来确保您没有执行任何可以在数据库上长时间锁定的查询。等等
答案 1 :(得分:3)
查看Illuminate\Config\Repository
哪个是用于Config
外观的实现,特别是set
方法
public function set($key, $value = null)
{
if (is_array($key)) {
foreach ($key as $innerKey => $innerValue) {
Arr::set($this->items, $innerKey, $innerValue);
}
} else {
Arr::set($this->items, $key, $value);
}
}
您可以放心,该集合不是IO集(即文件系统),而是内存集。因此,每分钟运行的CLI调度程序命令将像其他每个http请求一样在其自己的上下文中运行。