[firebase-br] Select em segundo plano?

Sandro Souza escovadordebits em gmail.com
Sáb Maio 7 10:04:07 -03 2011


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
>



Mais detalhes sobre a lista de discussão lista