Reputation: 13
The parent command below calls another child command asynchronously.
Parent Command
foreach ( $values as $value ) {
// asynchronous call
shell_exec(sprintf('php app/console {child command} %d > /dev/null &', $value));
}
Child Command
$em = $this->getContainer()->get('doctrine')->getEntityManager();
// some database action
When executing the parent command, the error below has occurred.
[PDOException]
SQLSTATE[HY000] [1040] Too many connections
I think there is the problem about the close of database connections.
So I added
$em->getConnection()->close();
in the last of the child command, but the result has not changed.
Upvotes: 1
Views: 1508
Reputation: 3442
the close()
did not help because you are sending processes to backgruond (because of &
at the end of command) which makes the commands execute in parallel. The problem is that you MySQL server has limited amount of maximum simultaneous connections.
What you can do is limit the spawning of processes, so you do not spawn e.g. more than 5 at a time is to wait for 5th process to finish before spawning another 5. This would be effective if those processes take similar amount of time to finish:
$i = 0;
foreach ( $values as $value ) {
$i++
// make asynchronous call for first 4 processes
if ($i < 5) {
shell_exec(sprintf('php app/console {child command} %d > /dev/null &', $value));
} else {
// wait for 5th process to finish before spawning more
shell_exec(sprintf('php app/console {child command} %d > /dev/null', $value));
$i = 0;
}
}
Then basically adjust the number of spawnable processes to what the limit of simultaneous connections on your MySQL server is set.
Upvotes: 1