Solucionado (ver solução)
Solucionado
(ver solução)
1
resposta

É necessário terminar a conexão com o banco usando connection.end() ? Onde chamá-lo?

Boa noite!

No primeiro curso de Node.js o instrutor explica que é importante finalizar uma conexão com o banco após criar uma conexão e fazer uma query. Já no segundo curso, estou vendo que não foi utilizado o método end na connection. Segue abaixo a maneira implementada na aula:

    ...
    app.post("/pagamentos/pagamento",function(req, res) {
      var pagamento = req.body;
      console.log('processando pagamento...');

      var connection = app.persistencia.connectionFactory();
      var pagamentoDao = new app.persistencia.PagamentoDao(connection);

      pagamento.status = "CRIADO";
      pagamento.data = new Date;

      pagamentoDao.salva(pagamento, function(exception, result){
        console.log('pagamento criado: ' + result);
        res.json(pagamento);
      });
    });
    ...

Outra dúvida é sobre onde utilizar o connection.end(), dentro do callback passado para pagamentoDao.salva ou após a chamada deste método (fora do callback)?

No primeiro curso o instrutor explicou que o connection.end() deveria ser utilizado fora do callback (aula 8 vídeo 1 aos 3:20), não me lembro do mesmo ter explicado o porquê.

Bem, a princípio, no meu entendimento de código assíncrono, o método deveria ser chamado no callback, isto porque logo após a chamada do método salva já temos o connection.end() e não necessariamente a nossa função de callback já teria feito o insert no banco. Portanto poderíamos finalizar a conexão antes de ter feito nosso insert.

Entretanto, ao pesquisar na página do módulo mysql no GitHub encontrei o seguinte:

Closing the connection is done using end() which makes sure all remaining queries are executed before sending a quit packet to the mysql server.

O fechamento da conexão é feito usando end(), o que garante que todas as consultas restantes sejam executadas antes de enviar um pacote de encerramento para o servidor mysql.

— Google Tradutor

Mais abaixo ainda sobre o end():

connection.end(function(err) {
  // The connection is terminated now
});

This will make sure all previously enqueued queries are still before sending a COM_QUIT packet to the MySQL server. If a fatal error occurs before the COM_QUIT packet can be sent, an err argument will be provided to the callback, but the connection will be terminated regardless of that.

Isso garantirá que todas as consultas previamente enfileiradas ainda estejam, antes de enviar um pacote COM_QUIT para o servidor MySQL. Se ocorrer um erro fatal antes que o pacote COM_QUIT possa ser enviado, um argumento err será fornecido ao retorno de chamada, mas a conexão será encerrada independentemente disso.

— Google Tradutor

Pelo que entendi sobre isso, mesmo que hajam consultas rodando no banco, o método end() irá aguardar que sejam finalizadas, e também é um método assíncrono.

Refletindo um pouco mais, pensei, e se eu estivesse fazendo 2 queries no banco? Em qual dos dois callbacks eu chamaria o end()? Eu não saberia qual dos callbacks terminaria por último... e se eu chamasse o end() em um dos callbacks, será que a minha outra query já teria começado a rodar? Ou seja, caso ela ainda não tivesse começado a rodar, o end() finalizaria a conexão e minha query não rodaria. Talvez por isso devemos deixar o método end() cuidar dessa complexidade, utilizando-o fora do callback.

Não sei se faz sentido o que eu falei, talvez eu já tenha respondido minha segunda dúvida, mas agradeço se alguém que saiba como isso funciona possa esclarecer.

Mas voltando à primeira dúvida, na aula deveria ter sido utilizado o connection.end() ?

Agradeço desde já!

1 resposta
solução!

Oi Pedro, tudo bem? Assincronia é um assunto complicadinho de tratar e prevê a execução. O uso do end não é obrigatório, mas é recomendado e é uma boa prática até.

Ele é pra ser feito ao final da querie mas isso pode variar muito de um contexto para outro, neste caso, neste código que postou eu não vejo onde encerrar a conexão, mas me parece que o ideal seria dentro do DAO.