Executando verificação de segurança...
1

Conexão com o Banco de Dados: Aberta ou Fechada?

Boa Noite, Tudo Bem?

Pessoal, possuo uma aplicação feita em Windows Forms com o uso de C#.

Eu tenho muitas funções com requisições ao banco de dados, um exemplo de uma função que realiza muitas requisições:

private void BTN_REALIZAR_PEDIDO_Click(object sender, EventArgs e)
        {
            if (Componentes.VERIFICAR_SE_OS_TEXT_BOX_ESTAO_PREENCHIDOS(TB_NOME_DO_CLIENTE, TB_CIDADE, TB_CEP, TB_BAIRRO, TB_ENDERECO, TB_ESTADO, TB_NUMERO_ENDERECO, TB_UF) == true)
            {
                if (LISTVIEW_CarrinhoCompra.Items.Count > 0)
                {
                    if (Componentes.RETIRAR_CARACTERES_INADEQUADOS_TELEFONE(MTB_TELEFONE.Text) != "" && CB_ENTREGADOR.Text != "")
                    {
                        if (BancoClientes.VERIFICAR_SE_TELEFONE_JA_ESTA_CADASTRADO(Componentes.RETIRAR_CARACTERES_INADEQUADOS_TELEFONE(MTB_TELEFONE.Text)) == true)
                        {
                            if (BancoPedidos.VERIFICAR_SE_CLIENTE_ESTA_COM_PEDIDO_ABERTO_PELO_TELEFONE(Componentes.RETIRAR_CARACTERES_INADEQUADOS_TELEFONE(MTB_TELEFONE.Text)) == false)
                            {

                            }
                            else
                            {
                                MessageBox.Show("Esse cliente já está com pedido aberto, finalize-o, para criar um novo pedido.", "Tente novamente", MessageBoxButtons.OK, MessageBoxIcon.Information);
                                return;
                            }
                        }
                        else
                        {
                            MessageBox.Show("É necessário que o cliente esteja cadastrado no sistema para realizar um pedido.", "Tente Novamente", MessageBoxButtons.OK, MessageBoxIcon.Information);
                            return;
                        }
                    }
                    else
                    {
                        MessageBox.Show("Erro, não foi possível confirmar o pedido, tente novamente", "Tente novamente", MessageBoxButtons.OK, MessageBoxIcon.Information);
                        return;
                    }
                }
                else
                {
                    MessageBox.Show("Você não adicionou nenhum produto no carrinho de compra!", "Tente Novamente", MessageBoxButtons.OK, MessageBoxIcon.Information);
                    return;
                }
            }
            else
            {
                MessageBox.Show("Nem todos os campos estão preenchidos, tente novamente!", "Erro", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
        }

Como pode-se perceber, por apenas um clique em um botão foi realizada duas requisições no banco.

No entanto, nessas requisições, a conexão é aberta e fechada:

public static bool Function(string Fun)
        {
            try
            {
                using (MySqlCommand Comando = CONEXAO_BANCO().CreateCommand())
                {
                    Comando.CommandText = "";
                    using (DataTable Data = new DataTable())
                    {
                        using (MySqlDataAdapter dataAdapter = new MySqlDataAdapter(Comando))
                        {
                            dataAdapter.Fill(Data);
                        }

                        if (Data.Rows.Count > 0)
                        {
                            return true;
                        }
                        else
                        {
                            return false;
                        }
                    }
                }
            }
            catch
            {
                throw;
            }
            finally
            {
                CONEXAO_BANCO().Close();
            }
        }

Eu posso deixá-las aberta ou não afetará no tempo de requisição?

Carregando publicação patrocinada...
1

Otavio, ótima pergunta! Em questão de performance, é inquestionável que deixar elas abertas será mais rápido, dado que abrir a conexão com o banco de dados é mais demorado do que só reutilizar uma conexão que estava aberta.

Mas mais rápido não necessariamente resulta em ser melhor. Digo isso, pois no Postgres por exemplo, abrir uma conexão com o banco de dados é milisegundos, por exemplo 10ms ou 50ms se o banco estiver no mesmo local que a aplicação. Não é muita coisa, mas é bem mais devagar do que uma query subsequente que custaria 0.1ms ou 1.6ms. Estou tirando esses valores aqui dos meus testes locais, pois neste exato momento estou rodando o serviço do TabNews localmente e pegando esses valores.

Agora, nas primeiras versões do TabNews, a gente abria e fechava a conexão a cada query e dava para usar o site. Ambas camadas da Aplicação e Banco estavam hospedadas na mesma região na AWS. Mas depois a gente fez uma nova abordagem para reutilizar o máximo que possível um pool de conexões, mesmo num ambiente serverless. Se você quiser acompanhar a pesquisa feita na época, veja essa issue que está dentro do repositório do módulo que usamos para se conectar ao banco.

De qualquer forma, eu não deixaria conexões abertas com o banco de dados sem serem reaproveitadas e gerenciadas por um pool. Pois se você só ficar abrindo conexões infinitamente sem fechar elas, rapidamente você irá esbarrar no limite máximo de conexões que o banco de dados consegue manter aberta.

Hoje no TabNews estamos usando a menor instância do RDS e ele possibilita no máximo 78 conexões abertas (isso já considera conexões reservadas para o super user do banco). Caso queira ver isso rodando em Produção, acesse o /status aqui do TabNews. Tem mais dados legais lá 🤝

1

Olá Filipe Deschamps, obrigado pelo resposta.

No meu caso, o banco de dados não está hospedado no mesmo local da minha aplicação. Enquanto que o banco de dados está hospedado em um serviço oferecido pela Hostinger, a minha aplicação roda em meu computador, em um aplicativo windows (como dito, feito em Windows Forms).

Apesar disso, continuarei utilizando esse método de Abrir a Conexão e Fechar, pois, apesar de ter encontrado algo semelhante sobre o pool dentro do C#, não possuo aprofundamento adequado.

Obrigado pela ajuda, grato.

2