Demora para desconectar banco

Firebird

29/09/2004

Amigos,

Estou enfentando um problema de demora para desconectar o banco de dados. O banco de dados, ainda teste está pequeno +- 700k, e até ontem estava funcionando bem, porém hoje começou a demorar muito para desconectar (uns 2 ou 3 minutos) em modo local.

Avaliando a execução do programa, vejo que a demora está na linha:

db.Connected := False;

Este comando está dentro do evento onDestroy do datamodule.

Já executei um gfix para ver se o banco está com problema, mas está tudo ok. O que poderia ser?


Aerreira

Aerreira

Curtidas 0

Respostas

Vinicius2k

Vinicius2k

29/09/2004

Colega,

É a primeira vez que presencio este problema, mas no meu entender esta linha não é necessária...
Na destruíção do Data Module, consequentemente seus ´filhos´ serão antes dele e o destroy do IBDatabase, faz todo o procedimento de fechamento de DataSets e desconexão automaticamente...
Pessoalmente, nunca me desconectei do banco ao fechar a aplicação... posso até estar errado neste procedimento...

Como não tenho certeza, embasei minha resposta no destructor do IBDatabase, veja :
destructor TIBDatabase.Destroy;
var
  i: Integer;
begin
  if FIBLoaded then
  begin
    IdleTimer := 0;
    if FHandle <> nil then
    try
      Close;
    except
      ForceClose;
    end;
    for i := 0 to FSQLObjects.Count - 1 do
      if FSQLObjects[i] <> nil then
        SQLObjects[i].DoDatabaseFree;
    RemoveSQLObjects;
    RemoveTransactions;
    FInternalTransaction.Free;
    FreeMem(FDPB);
    FDPB := nil;
    FDBParams.Free;
    FSQLObjects.Free;
    FUserNames.Free;
    FTransactions.Free;
    FEventNotifiers.Free;
    FSchema.Free;
  end;
  FGDSLibrary := nil;
  inherited Destroy;
end;


Espero ter ajudado...
T+


GOSTEI 0
Aerreira

Aerreira

29/09/2004

Na destruíção do Data Module, consequentemente seus ´filhos´ serão antes dele e o destroy do IBDatabase, faz todo o procedimento de fechamento de DataSets e desconexão automaticamente...


Bom então não preciso tomar nenhum procedimento para fechar o banco, perfeito. Mas acho que meu problema é outro, pois estava funcionando mesmo com o db.connected := false, e agora coloquei todo o conteúdo do OnDestroy do DataModule como comentário e minha aplicação continua travando na saida.

Nas propriedades do FireBird Server ficam constando:
Number of attachments: 5
Number of databases: 1
Quando a aplicação encerra, os valores acima são zerados.

Tá difícil de descobrir...


GOSTEI 0
Vinicius2k

Vinicius2k

29/09/2004

Este é um problema novo para mim... e, ao menos pelo que sei, se vc só estiver com a sua aplicação rodando no momento q pede as propriedades do FB Server, deveria constar 1 Attachment e 1 Database... ou no máximo 2 Attachments se vc estiver debugando por dentro do Delphi.

Honestamente, não sei o que pode ser... aparentemente, seu IBDatabase está replicado algumas vezes... se é que isto é possível.

O que eu posso lhe sugerir, e não tenho certeza se é a causa do problema é:
1. Atualize seu IBX (se eu não estiver enganado, vc já o fez):
http://codecentral.borland.com/codecentral/ccweb.exe/author?authorid=102
2. Certifique-se de q vc está usando uma versão estável do FB
1.0 -> 1.0.3.972
1.5 -> 1.5.0.4306
1.5.1 -> 1.5.1.4481

T+


GOSTEI 0
Aerreira

Aerreira

29/09/2004

Honestamente, não sei o que pode ser... aparentemente, seu IBDatabase está replicado algumas vezes... se é que isto é possível. 1. Atualize seu IBX (se eu não estiver enganado, vc já o fez): http://codecentral.borland.com/codecentral/ccweb.exe/author?authorid=102


Atualizei esta semana para IBX 5.04 D5-SP1


2. Certifique-se de q vc está usando uma versão estável do FB 1.0 -> 1.0.3.972 1.5 -> 1.5.0.4306 1.5.1 -> 1.5.1.4481


Acho que minha versão do Firebird é 1.0.0.796. Vou atualizar.

Mas acho que achei o problema. Eu estava usando IbTable direto (já sei que não deveria...) estarei migrando tudo para IBDataSet. Eu estou abrindo todas as tables (umas 25) no inicio da aplicação, acho que isso também não é bom.

Pergunto:
1) Convém abrir todos os datasets no inicio da aplicação ou é melhor abrir os datasets menos usados somente no momento em que forem necessários?

2) Relacionamentos master/detail são feitos apenas pelas PK e FK das tabelas ou é preciso definir os wheres dos selects ?

[]s


GOSTEI 0
Aerreira

Aerreira

29/09/2004

2. Certifique-se de q vc está usando uma versão estável do FB 1.0 -> 1.0.3.972 1.5 -> 1.5.0.4306 1.5.1 -> 1.5.1.4481


Atualizei o Firebird para 1.0.3 e o problema sumiu!!!

Ainda assim, preciso trocar as IBTables por IBDataSets mas estou tendo dificuldade para fazer os relacionamentos master/detail...


GOSTEI 0
Vinicius2k

Vinicius2k

29/09/2004

:D
Que bom q o problema se foi !

Sobre as suas perguntas...

1. Só abra o DataSet quando abrir o form ou executar a rotina onde ele será necessário... Abrir tudo compromete a performance da aplicação e, como vc estará trabalhando com dados em cache de memória, vc desperdiça uma chance de exibir os dados atualizados ao usuário. Quando fechar o form, feche o DataSet.

2. Eu sempre fiz master/details ´manuais´... no OnChangeData do DataSource Master eu fecho, passo a(s) chave(s) como parametro(s), e abro o Detail... Sinceramente, não sei lhe dizer se esta eh a melhor forma, mas sempre trabalhei assim, desde os tempos da BDE, pq sempre trabalhei com Queries, mesmo em bancos Desktop.
PKs e FKs são relacionamento no lado do servidor, e sua únicas funções são auxiliar na indexação e garantir a integridade referencial. O relacionamento no lado do cliente precisa ser feito por vc.

O colega afarias tem mais experiência com DataSets aninhados que seria a segunda forma se fazer o Master/Detail.

Anderson, quando ler este tópico, peço que oriente o colega com relação a aninhamentos no IBX... :wink:

T+


GOSTEI 0
Aerreira

Aerreira

29/09/2004

2. Eu sempre fiz master/details ´manuais´... no OnChangeData do DataSource Master eu fecho, passo a(s) chave(s) como parametro(s), e abro o Detail...


Ok, suas explicações estão sendo muito valiosas, obrigado. Agora eu acho que o esquema que me passou acima talvez fique meio lento em alguns casos, por exemplo: tenho neste sistema um relacionamento Proprietários / Imóveis / Contratos e quando navego pelos proprietários os imóveis e contratos respectivos também são atualizados na mesma tela. Idem para navegação nos imóveis que faz atualização do detail contratos. Será que ficar abrindo, mudando parâmetros e fechando em cada registro que o usuário visualizar não vai ficar muito lento não?

O colega afarias tem mais experiência com DataSets aninhados que seria a segunda forma se fazer o Master/Detail. Anderson, quando ler este tópico, peço que oriente o colega com relação a aninhamentos no IBX... :wink:


Acho que talvez essa forma de Nested Datasets possa ser uma solução mais rápida para este meu caso... AFarias, poderia me exclarecer o aninhamento de datasets melhor, pois o que lí no forum sobre o assunto ainda não foi suficiente para que eu compreenda como implementar.

Grato a todos,


GOSTEI 0
Afarias

Afarias

29/09/2004

|Será que ficar abrindo, mudando parâmetros e fechando em cada
|registro que o usuário visualizar não vai ficar muito lento não?

Com as devidas chaves extrangeiras (ou índices) criadas geralmente q não. Esta solução é perfeita. Mas, para evitar fazer código vc pode apenas usar a forma ´padrão´ do Delphi:

Coloque um datasource ´ligado´ ao DataSet (IBDataSet ou IBQuery) mestre. No dataset ´detalhe´ coloque um SQL na forma::

select * from tabelatal where campo_chave_est = :campo_chave_prim

onde o parâmentro ´campo_chave_prim´ tem o mesmo nome do ´campo chave primária´ na tabela ´mestre´, então ´ligue´ a propriedade DataSource deste dataset ´detalhe´ ou datasource que falamos anteriormente (da tabela mestre)

pronto, ao navegar pela mestre, os registros do DataSet detalhe serão automáticamente ´filtrados´ (o SELECT será re-executado)


|Acho que talvez essa forma de Nested Datasets possa ser uma solução
|mais rápida para este meu caso...

Nested DataSets realizam a completa busca de todos os registros detalhes para cada meste para memória. Em muitos casos isso é MENOS eficiente q a solução mais simples discutida anteriormente (principalmente em aplicações em uma rede local e q precisa carregar muitos mestres)

Além do mais, exige o uso de MIDAS (ClientDataSets e DataSetProviders) os quais, se vc não está usando, vai exigir um certo estudo de sua parte nesses componentes.

Se realmente decidir partir para uma solução assim, post outros tópicos perguntando sobre o assunto (ou leia os já existentes no fórum)


T+


GOSTEI 0
Aerreira

Aerreira

29/09/2004

Com as devidas chaves extrangeiras (ou índices) criadas geralmente q não. Esta solução é perfeita. Mas, para evitar fazer código vc pode apenas usar a forma ´padrão´ do Delphi:


Funcionou perfeitamente fazendo a ligação da propriedade datasource do DataSet-Detalhe ao componente DataSource do DataSet Master. Fiz o relacionamento entre três tabelas (proprietários / imóveis / contratos) e funcionou perfeitamente e não ficou lento.

Agora compreendi melhor. A propriedade datasource do IBDataSet é o equivalente ao Mastersource do TTable ou IBTable, certo?

Nested DataSets realizam a completa busca de todos os registros detalhes para cada meste para memória. Em muitos casos isso é MENOS eficiente q a solução mais simples discutida anteriormente (principalmente em aplicações em uma rede local e q precisa carregar muitos mestres). Além do mais, exige o uso de MIDAS (ClientDataSets e DataSetProviders) os quais, se vc não está usando, vai exigir um certo estudo de sua parte nesses componentes.


Ok, já desisti dos Datasets aninhados...

Valeu amigos, acho que agora já posso andar com minhas pernas por um tempo... Qualquer coisa posto aqui no forum...


GOSTEI 0
Afarias

Afarias

29/09/2004

|Agora compreendi melhor. A propriedade datasource do IBDataSet é o
|equivalente ao Mastersource do TTable ou IBTable, certo?

Certo!



T+


GOSTEI 0
Mordred

Mordred

29/09/2004

Notei que as telas em que uso master-detail estão ficando bastante lentas.
Uso os componentes da paleta Interbase e minha tabela já possui um índice de chave primária e dois índices de chaves estrangeiras. É necessário criar mais algum índice além desses índices automáticos?
O que posso estar fazendo de errado e como posso corrigir esse erro terrível? Alguém tem alguma sugestão?


GOSTEI 0
POSTAR