Clipper On Line • Ver Tópico - Reaproveitamento de conexão MySQL
Mudar para estilo Clássico
Discussão sobre Banco de Dados e RDDs para Clipper/[x]Harbour.
Postar uma resposta

Reaproveitamento de conexão MySQL

20 Abr 2017 18:05

Tenho usado MySQL há cerca de 2 anos, sempre fazendo assim:

1) conecto ao banco de dados com RDDINFO
2) executo a query
3) desconecto

Acontece que meu sistema faz isso o tempo todo, são várias conexões seguidas. E isso tem me gerado alguns problemas, pois às vezes, não sei porquê, a conexão não se desfaz. Daí estoura o número de conexões no provedor.

Pelo que estive pesquisando, é possível usar uma mesma conexão para executar várias querys seguidas, inclusive com a vantagem de o procedimento ganhar velocidade. Pelo que eu entendi, seria algo assim:

1) conecta ao banco de dados
2) executa a query 1
3) executa a query 2
4) executa a query 3
....
x) desconecta

A minha dúvida é: isso funciona bem assim? Existe algum risco nesse procedimento? Resolveria o meu problema de excesso de conexões? Essa mesma conexão poderia ficar ativa durante horas em que o sistema é utilizado? Pelo que vi, o meu provedor tem um timeout para conexões de 7200s (o que daria 2 horas), mas parece que esse tempo seria só para conexão inativa, certo? Se a conexão ficar sendo usada o tempo todo, não haveria problema, correto?

Reaproveitamento de conexão MySQL

20 Abr 2017 19:24

Olá!

cjp escreveu:é possível usar uma mesma conexão para executar várias querys seguidas,


Não conheço e nunca usei RDDINFO.

Sei que isto é possível usando-se ADO. Já usei e funciona.

Reaproveitamento de conexão MySQL

21 Abr 2017 00:07

Estranhamente, não estou conseguindo fazer isso.

Quando saio da função que executa a query, ao voltar, não consigo usar a mesma conexão.

Tem algum jeito de forçar o uso da mesma conexão?

Reaproveitamento de conexão MySQL

21 Abr 2017 21:22

O Windows tem vários limites de tempo.
Tem tempo pra conexão ociosa, tempo pra terminal ocioso, etc.
Alguns ficam executando querys a cada intervalo de tempo só pra manter a conexão ativa.
E se a conexão é externa, tem também o risco de cair internet.

Pelo menos em ADO, é assim que uso: uma única conexão, aberta ao iniciar o aplicativo, e fechada no final.

Reaproveitamento de conexão MySQL

21 Abr 2017 21:31

Entendi. Mas, no caso, eu verifiquei que a conexão está ativa ainda. Só que não sei como usá-la. Da forma como está minha aplicação, ela abre automaticamente nova conexão, deixando a anterior ativa. Como evito isso?

Reaproveitamento de conexão MySQL

27 Abr 2017 16:56

Inácio, faz o que o JoséQuintas falou, faz a conexão apenas uma vez no início do programa (no PRG principal/inicial) e só desconecta quando for finalizar o programa. Ai quando for executar as querys, não precisa conectar novamente, apenas construa a query e execute ela.

Abraços,

Reaproveitamento de conexão MySQL

27 Abr 2017 17:21

Então, é isso que estou tentando fazer, mas, não sei porquê, não estou conseguindo.

Tenho uma função específica para executar as querys com update, outra específica para fazer select. Ambas chamam a função de conexão. Atualmente, elas conectam chamando a função de conexão, executam as suas querys, depois desconectam.

Daí tentei fazer como ele disse: conectar uma só vez no início, depois executar as querys diretamente, sem nova conexão, retirando a chamada à função de conexão das duas funções anteriores e retirando também a desconexão no final delas. Mas daí dá erro por falta de conexão.

O mais estranho é que, aparentemente, permanece a conexão ativa. Tanto é que, tentando fazer nova conexão, o número da nova conexão é o próximo em sequência, não é o mesmo anterior.

Estou fazendo assim para testar:

Código:
function testesdiversos

private nConnection
   
nConnection :=conecta(1)
   
do while .t.
   if dbsel("select * from tarefas where nrtarefa='Z800'","testesd",1)>0
      ?nConnection
   endif   
enddo      


A função dbsel é a que executa o select:

Código:
function dbsel(sel,nmbs,nServidor)
         local nvz :=1
       local sair :="N"
       private cMessage
       if nmbs=NIL
          nmbs=procname(1)
        endif
         do while .t.
          if nvz>1 .and. ("gone away"$cMessage .or. "Not connected"$cMessage .or. "abertura"$cMessage)
            nConnection=conecta(nServidor)
         endif
         if nConnection=0
            return 0
         endif
            bError := ErrorBlock( {|e| Break(e) } )
            begin sequence
               use
                  dbusearea(.f.,,sel,nmbs+substr(time(),4,2))
               sair="S"
            recover using e
                  RDDSETDEFAULT("DBFNTX")
              nvz++
                 cMessage := ErrorMessage(e)
                if at("Lost connection",cMessage)=0 .and. at("Unable to get error",cMessage)=0 .and. at("Erro de abertura",cMessage)=0
                    logerro()
               endif
              if nvz>2
                     mandmail1("error.log","Erro no dbsel contornado com o recover do begin sequence: "+cmessage)
                 return 0
               endif
            endsequence
            ErrorBlock( bError )
         if sair="S"
            exit
         endif
       enddo
         RDDSETDEFAULT("DBFNTX")
       fAtiva=.f.
return nConnection


Note que, teoricamente, era pra ela executar diretamente o Select, pois a conexão já foi feita antes de ela ser chamada, mas ela não está executando, tá dando o erro, daí eu trato o erro fazendo nova conexão.

O que eu estou fazendo errado?

Reaproveitamento de conexão MySQL

27 Abr 2017 23:31

Rotina inexplicável.
Não uso isso, mas por acaso não dá pra fazer um teste assim:

Código:
FUNCTION TestesDiversos()

   LOCAL nCont, lOk, nConnection

   nConnection := conecta( 1 )

   FOR nCont = 1 TO 10
      lOk := .F.
      BEGIN SEQUENCE WITH __BreakBlock()
         dbUseArea( .F.,, "SELECT * FROM TAREFAS WHERE NRTAREFA='Z800'" )
         lOk := .T.
      END SEQUENCE
      USE
      ? "SELECT " + iif( lOk, "OK", "COM ERRO" )
   NEXT
   
   RETURN

Reaproveitamento de conexão MySQL

28 Abr 2017 02:56

Entendi a lógica do teu exemplo e testei. Era pra funcionar, mas está dando SELECT COM ERRO.

O conecta retornou 1, ou seja, foi conectado. Não era pra funcionar?

Reaproveitamento de conexão MySQL

28 Abr 2017 07:27

Então reduza mais ainda pra ver qual é o erro.

Código:
FUNCTION TestesDiversos()

LOCAL nCont, nConnection

nConnection := conecta( 1 )

FOR nCont = 1 TO 10
    dbUseArea( .F.,, "SELECT * FROM TAREFAS WHERE NRTAREFA='Z800'" )
   USE
NEXT

RETURN

Reaproveitamento de conexão MySQL

28 Abr 2017 09:28

Comentário:

Mesmo que a conexão funcione, precisa ver se o select está certo, se o usuário tem direito de acesso a essa tabela, etc.

Além disso, não sei exatamente nesse seu uso, se precisa algo mais.

Uma coisa é o MySQL, outra coisa é o Harbour, e outra coisa é o componente usado pra trabalhar com MySQL no Harbour.

Problema de Harbour, quem com Harbour sabe.
Problema de MySQL, quem com MySQL sabe.
Problema com esse componente: só quem usa esse mesmo componente, o que restringe a quem usar Harbour + MySQL + esse componente..

Deixe que apareçam as mensagem de erro, pra pelo menos saber do que se trata o erro.

Reaproveitamento de conexão MySQL

28 Abr 2017 23:56

Descobri o erro, muito elementar: no teu exemplo, o nome da tabela estava com maiúsculas, na base de dados está em minúsculas, daí deu tabela inexistente.

Corrigi e funcionou. Inclusive funcionaram os vários selects com uma só conexão.

Depois de vários testes, descobri também porque não estava funcionando na minha função dbsel() e já resolvi o problema.

Obrigado pela ajuda.

Mas me resta um problema: meu provedor atual tem umas restrições complicadas de tamanho e, por causa disso, eu tive que separar minhas tabelas em vários bancos de dados. E o pior é que em cada banco de dados tem um usuário diferente, pois o provedor não permite que eu escolha o nome dos usuários, ele mesmo que atribui o nome. Assim, eu tenho que ter uma conexão diferente para cada banco de dados, com um total de 4 conexões diferentes, que são usadas alternativamente em todo o sistema.

A pergunta é: tem como ficar conectado nos 4 bancos ao mesmo tempo? E como eu faria para escolher a conexão de acordo com o banco que será usado?

Reaproveitamento de conexão MySQL

29 Abr 2017 08:40

Até tem jeito, mas se for relacionar uma tabela com a outra, não vai conseguir.

Se for provedor pago, troque de provedor.

Reaproveitamento de conexão MySQL

29 Abr 2017 09:49

E pago sim, mas este é o melhor provedor de todos os que já testei. E o acesso mais rápido e confiável (com menos falhas). Por isso, por hora, não estou considerando trocar. Sem prejuízo de testar outros que me indicarem.

Não pretendo relacionar tabelas, apenas usar varias ao mesmo tempo. Poderia me indicar como fazer isso?

Reaproveitamento de conexão MySQL

29 Abr 2017 10:35

cjp escreveu:tem como ficar conectado nos 4 bancos ao mesmo tempo? E como eu faria para escolher a conexão de acordo com o banco que será usado?

Sim, você pode conectar em vários banco de dados. Agora para escolher a conexão, veja o último parâmetro da função DbUseArea:

DbUseArea( [<lNewArea>] , ;
[<cRddName>] , ;
<cDatabase> , ;
[<cAlias>] , ;
[<lShared>] , ;
[<lReadonly>] , ;
[<cCodePage>] , ;
[<nConnection>] )
...
<nConnection>
This parameter specifies a numeric server connection handle. It is returned by a server connection function which establishes a connection to a database server, such as SR_AddConnection() of the xHarbour Builder SQLRDD. When <nConnection> is passed, the function opens a database on the server.


Abraços,
Postar uma resposta