Solucionado (ver solução)
Solucionado
(ver solução)
7
respostas

muitos insert ao mesmo tempo

O código abaixo funciona bem sendo carregado um a um:

$capture = new Capture();
$capture->setDatetime($datetime);

$keyword = new Keyword();
$keyword->setKeyword($body->breadCrumb->keywords);
$find = $entityManager->getRepository('TesteBot\Teste\JsonToDb\Entity\Keyword')
    ->findOneBy(['keyword' => $keyword->getKeyword()]);
if ($find) $keyword = $find;
$capture->setKeyword($keyword);

$entityManager = reopenEntityManagerIfClosed($entityManager);
$entityManager->persist($capture);
$entityManager->flush($capture);

Porém para acelerar o processo sem usar pthreads, usei o popen:

for ($i=0; $i<10; $i++) {
    // open ten processes
    for ($j=0; $j<10; $j++) {
        $pipe[$j] = popen('script2.php', 'w');
    }

    // wait for them to finish
    for ($j=0; $j<10; ++$j) {
        pclose($pipe[$j]);
    }
}

E começou a retornar o seguinte erro:

2020-12-08 00:33:13 - 2020-12-02 09:04:06.json - PDOException: SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry 'Papelaria Adesivo' for key 'Keyword.UNIQ_952E48A75A93713B' in /home/edison/Documentos/bots/teste-bot/teste-json-to-db/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOStatement.php:115
Stack trace:
#0 /home/edison/Documentos/bots/teste-bot/teste-json-to-db/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOStatement.php(115): PDOStatement->execute()
#1 /home/edison/Documentos/bots/teste-bot/teste-json-to-db/vendor/doctrine/dbal/lib/Doctrine/DBAL/Statement.php(167): Doctrine\DBAL\Driver\PDOStatement->execute()
#2 /home/edison/Documentos/bots/teste-bot/teste-json-to-db/vendor/doctrine/orm/lib/Doctrine/ORM/Persisters/Entity/BasicEntityPersister.php(286): Doctrine\DBAL\Statement->execute()
#3 /home/edison/Documentos/bots/teste-bot/teste-json-to-db/vendor/doctrine/orm/lib/Doctrine/ORM/UnitOfWork.php(1097): Doctrine\ORM\Persisters\Entity\BasicEntityPersister->executeInserts()
#4 /home/edison/Documentos/bots/teste-bot/teste-json-to-db/vendor/doctrine/orm/lib/Doctrine/ORM/UnitOfWork.php(402): Doctrine\ORM\UnitOfWork->executeInserts()
#5 /home/edison/Documentos/bots/teste-bot/teste-json-to-db/vendor/doctrine/orm/lib/Doctrine/ORM/EntityManager.php(371): Doctrine\ORM\UnitOfWork->commit()
#6 /home/edison/Documentos/bots/teste-bot/teste-json-to-db/command/json-to-db-popen-2.php(97): Doctrine\ORM\EntityManager->flush()
#7 {main}

Eu gostaria de saber se existe alguma forma de subir os arquivos de forma concorrente? Não tem insert/update igual o eloquent? se duas pessoas acessarem ao mesmo tempo o sistema e fizerem uma inserção na mesma chave unica com mesmo valor entao o sistema falha?

7 respostas
solução!

Edson, programação paralela não é para casos onde há muito I/O. Assista esse vídeo aqui: https://www.youtube.com/watch?v=zLfXPSeCkB8

Quanto ao seu problema, basta fazer o foreach com o persist e deixar o flush fora do loop. O Doctrine só vai no banco quando o flush é chamado, então vai ser apenas uma ida ao banco. ;-)

Oi Vinícius. Boa funcionou!!! Assisti o video, muito legal também. coloquei o find fora do loop tb e aparentemente ficou mais rápido também. Só que dá aqueles pico de cpu. Eu queria se for possível que vc me ensinasse a instalar aquele docker integrado com phpstorm com php8 e jit que vc mostra lá no canal. Bem show também. Acho q vai melhorar mais um pouco, mas se não der para mostrar blz, assim já está atendendo. Valeu mesmo!!!

Olá, Edson. Não tem segredo. Só configurar na parte de interpretador PHP lá no PHPStorm como uma imagem Docker

Tem razão é facinho. Obrigado. Percebi que otimizou bem a CPU. Outra coisa que melhorou foi que coloquei tudo num ssd. Vinicius, já tem um tempo que procuro um lugar que explique direitinho como funciona injeção de dependencias em php, prrocurei aqui no alura e no dias de dev e não encontrei nada. Se tiver algum material me passa o link por favor?

Opa, fico feliz que tenha resolvido e que conheça meu canal.

Vê se isso te ajuda: https://cursos.alura.com.br/injecao-de-dependencias-o-que-e--c224

Muito legal seu canal!

Olha o que eu não estou entendendo:

Eu estava tentando aprender por aqui: https://code.tutsplus.com/tutorials/examples-of-dependency-injection-in-php-with-symfony-components--cms-31293

E tem o repositório também: https://github.com/tutsplus/examples-of-dependency-injection-in-php-with-symfony-components

e criar um arquivo teste.php

<?php
require_once './vendor/autoload.php';
use Services\DependentService;

echo (new DependentService())->helloWorld().PHP_EOL;

Não era para ele instanciar automático? Ele está pedindo parâmetro.

O jeito que ele ensina acessando:

$dependentService = $containerBuilder->get('dependent.service');
echo $dependentService->helloWorld();

dentro do di_container.php para mim não serve pra nada. Eu queria usar a classe DependentService em um outro arquivo separado já com as dependências

Ah, seu problema não está no conceito, e sim na prática de um container de di .

Se eu não me engano, no curso de MVC eu mostro como se usa o php-di. Talvez faça mais sentido.

No ponto principal da aplicação a gente cria o Controller usando o container. Todas as dependências dali em diante o container resolve, entende?

Quer mergulhar em tecnologia e aprendizagem?

Receba a newsletter que o nosso CEO escreve pessoalmente, com insights do mercado de trabalho, ciência e desenvolvimento de software