[firebase-br] Select em segundo plano?

Marcos Weimer marcosweimer em gmail.com
Sáb Maio 7 10:27:59 -03 2011


Ola!

Desculpe pela intromissão...
mas esse assunto é muito interessante. Se forem continuarem fora... se
possivel, me avisem. Assuntos desse tipo não vi em listas delphi.

Obrigado.

Em 7 de maio de 2011 10:04, Sandro Souza <escovadordebits em gmail.com>escreveu:

> Bom dia/tarde Felix.
>
> Nobre amigo, eu já implementei esse esquema, e posso lhe dizer com base na
> minha experiência que é totalmente viável.
>
> O Firebird, como qualquer outro SGBD, é feito para receber várias conexões.
>
> É transparente para o Firebird (alias para qualquer programa servidor que
> receba conexões de TCP/IP) se as conexões provem de várias aplicações ou de
> várias threads dentro de uma aplicação. Pois dá no mesmo.
>
> Só preciso lhe avisar que você tem que tomar alguns cuidados importantes em
> fazer acesso multithread ao banco de dados em aplicações feitas em Delphi
> (e
> acredito que em C++ Builder também), pois a unidade "DB.pas" onde está
> declarada a classe TDataSet que serve de base p/ todos os tipos de DataSets
> (tabelas, queries, etc...) não foi feita pensando em um ambiente
> multithread, e portanto não foi implementada de forma "threadsafe".
>
> Pude comprovar isso quando desenvolvi uma aplicação servidora que recebe
> várias conexões de TCP/IP, gerando uma thread separada p/ tratar cada
> conexão, em paralelo, e executar operações no banco de dados.
>
> Revisando o código fonte da unidade DB.pas, pude notar que a classe
> TDataSet
> acessa alguns objetos (alguns são globais) da mesma unidade sem qualquer
> preparo p/ enfrentar um ambiente interno de multithread.
>
> Na prática, quando coincide de uma operação de um DataSet de uma thread for
> executada no mesmo momento em que outra operação de DataSet estiver sendo
> executada em outra thread faz com que a aplicação TODA fique travada, sem
> apelação mesmo.
>
> Por exemplo, um "Open" em uma query da thread 1 coincidir de ser executado
> ao mesmo tempo de um "Next" em uma query da thread 2. Pode testar e também
> comprovar por si mesmo. Não tem nada a ver com o Firebird, mas sim como
> foram implementadas as classes da unidade DB.pas, afetando todas as classes
> descendentes. :(
>
> Resolvi essa questão usando semáforos, que é o mecanismo ideal p/ essas
> situações. Até porque, semáforos são naturalmente uma parte essencial de
> uma
> aplicação multithread.
>
> Dê uma olhada nas funções CreateSemaphore (criar um novo semáforo),
> WaitForSingleObject (aguardar a permissão/sinalização de um semáforo ou
> outro tipo de objeto), ReleaseSemaphore (devolver a permissão ao semáforo)
> e
> CloseHandle (fechar e liberar praticamente todos os tipos de recursos
> dentro
> do M$ Windows).
>
> Acabei criando uma classe descendente da query que eu estava usando, e em
> cada método (dentro de cada método) dessa nova query (Open, Next, etc...)
> eu
> aguardo a permissão de um único semáforo global p/ as operações de banco de
> dados, faço o que devo fazer, e devolvo a permissão logo antes de sair do
> método.
>
> Dessa forma, consegui serializar as operações de banco de dados, como se
> fosse uma aplicação normal ("café com leite"), mas podendo trabalhar
> tranquilamente com várias threads.
>
> Além disso, as alterações no código já existente foram as mínimas
> possíveis,
> pois bastou apenas trocar a classe da query que estava sendo criada, da
> antiga (TIBQuery) pela nova (TThreadSafeIBQuery), e mantive o todo o
> restante do código exatamente como estava.
>
> Acho que a sua idéia de criar uma thread p/ fazer a pesquisa (ou qualquer
> outro tipo de operação de banco de dados que possa demorar e causar algum
> aborrecimento ao usuário) pode e deve ser feita em thread.
>
> Se você desejar, podemos continuar a conversa fora do fórum p/ não
> prolongar
> esse assunto que realmente é off-topic.
>
> Espero ter ajudado mais que atrapalhado. :D
>
> Em 6 de maio de 2011 11:34, Felix <felix.sol em terra.com.br> escreveu:
>
> > Senhores,
> >
> > Eventualmente alguma pesquisa pode ser mais demorada (digamos, 2 minutos)
> e
> > o usuário fica impaciente, achando que a máquina 'travou', apesar do
> > sistema
> > informar que está processando (label estático).
> >
> > Pergunta: é viável colocar o select em segundo plano, como uma Thread ?
> >
> > Obrigado,
> >
> > Fco. Felix
> > Desenvolvimento de Sistemas
> > www.soltecnologia.com.br
> >
> >
> > ______________________________________________
> > FireBase-BR (www.firebase.com.br) - Hospedado em www.locador.com.br
> > Para saber como gerenciar/excluir seu cadastro na lista, use:
> > http://www.firebase.com.br/fb/artigo.php?id=1107
> > Para consultar mensagens antigas: http://firebase.com.br/pesquisa
> >
> ______________________________________________
> FireBase-BR (www.firebase.com.br) - Hospedado em www.locador.com.br
> Para saber como gerenciar/excluir seu cadastro na lista, use:
> http://www.firebase.com.br/fb/artigo.php?id=1107
> Para consultar mensagens antigas: http://firebase.com.br/pesquisa
>



-- 
-=Ma®©oS=-
Marcos R. Weimer
Puma GTE 1974 Tubarão



Mais detalhes sobre a lista de discussão lista