Threads x SQL

Delphi

09/09/2006

Boa tarde!

Montei uma thread que se passa o parâmetro um ClientDataSet para abrir.

Intúito: Enquanto o(s) ClientDataSet(s) esta sendo aberto mostrar uma
barra de progresso enganosa, só para a APP não parecer travada.

Até ai tudo bem, vi que FUNCIONA blz, agora percebi que as threads tem um recurso interessante, que é pausar, e continuar, verifiquei que se pode pausar uma busca, cancelar, e continuar quando desejado, mas...

1º Essas operações podem afetar de alguma forma a estabilidade do servidor de BD? (no caso firebird)

2º Podem Prejudicar a estabilidade da APP em si?

3º Pela lógica não, mas pode acontecer de alguma perda de dados pelo fato de pausar a SQL?

Agradeço a atenção.

Código da Thread:


unit uTread;

interface

uses
  Classes , dbclient , db , forms;

type
  TOpenSQl = class(TThread)
  private
    dsForOpen : TdataSource;
    qr        : Tdataset;
    procedure OpenCDS;
    procedure connectDataSource;
    procedure disconnectDataSource;
  protected
    procedure Execute; override;
  public
    constructor create(ds : TdataSource);
  end;

implementation

uses Unit1;

{ Important: Methods and properties of objects in visual components can only be
  used in a method called using Synchronize, for example,

      Synchronize(UpdateCaption);

  and UpdateCaption could look like,

    procedure TOpenSQl.UpdateCaption;
    begin
      Form1.Caption := ´Updated in a thread´;
    end; }

{ TOpenSQl }

procedure TOpenSQl.connectDataSource;
begin
  dsForOpen.dataset := qr;
end;

constructor TOpenSQl.create(ds: TdataSource);
begin
  inherited create(true);
  dsForOpen := ds;
end;

procedure TOpenSQl.disconnectDataSource;
begin
   qr := dsForOpen.dataset;
   dsForOpen.dataset := nil;
end;

procedure TOpenSQl.Execute;
begin
   Synchronize(disconnectDataSource);
   OpenCDS;
   Synchronize(connectDataSource);
  { Place thread code here }
end;

procedure TOpenSQl.OpenCDS;
begin
   qr.open;
end;

end.



Chapolin

Chapolin

Curtidas 0

Respostas

Dmalta

Dmalta

09/09/2006

Boa pergunta, Chapolin! :D

A princípio, já seria um problema deixar o usuário pausar a consulta porque vai manter uma transação aberta, e isso vai criar problemas inerentes a uma transação longa - desde o acúmulo de lixo no log de transações do servidor até o travamento de acesso concorrente de leitura e/ou gravação por outros usuários.

Outro ponto problemático é que não temos controle sobre a arquitetura de diversas camadas de interoperabilidade que fazem o acesso a dados: tem os componentes da VCL Delphi, frameworks de acesso a dados como Microsoft ADO, bibliotecas clientes nativas do banco de dados, middleware de conectividade (COM), middleware de rede (TCP/IP, sockets) do sistema operacional e tem o próprio gerenciador de banco de dados (FB, IB, MSSQL, Oracle...)

Como cada um desses irá se comportar à suspensão de uma query? Você pode testar e ver no que dá. De qualquer forma, eu não confiaria muito nesses testes, porque não temos como prever o comportamente dessas tantas ´caixas pretas´ que estão no caminho em situações específicas e comprometer a integridade da aplicação.

Por outro lado, alguns sistemas de BD têm suporte nativo ao [i:4ae2c56af1]cancelamento[/i:4ae2c56af1] de queries. Se for o caso, isso deve ser tranquilo. Suspender, no entanto, eu não conheço nenhum banco de dados ou middleware que dê suporte. No meu entender é totalmente [i:4ae2c56af1]anti-relacional[/i:4ae2c56af1], por causa do problema das transações.


GOSTEI 0
Chapolin

Chapolin

09/09/2006

certo, me convenci que realmente pausar seria um ônus que pode custar muito caro.

E quanto a forma que estou fazendo para abrir a query dentro da thread, esta correto?

qual a regra para que eu deva chamar o método pelo syncronize?

pois se eu mandar o syncronize abrir o dataset, vai ficar travado pois é a thread principal que abre, jogando fora todo objetivo.


obrigado pela atenção!


GOSTEI 0
Dmalta

Dmalta

09/09/2006

Está certo, sim.

A regra para chamar [b:788ec29291]Synchronize[/b:788ec29291] é que deve ser usado sempre e somente quando quiser mexer com qualquer propriedade visual ou variável global na aplicação, porque isso seria entrar no ´domínio´ da thread principal do programa.

Essa unit faz Synchrinze quando conecta e quando disconecta do DataSource porque presume que objetos visuais, como um TDBGrid, estejam ligados a ele.


GOSTEI 0
Dmalta

Dmalta

09/09/2006

Outra coisa, adicione no método Create essa linha, para liberar automaticamente o objeto Thread da memória quando o dataset terminar de ser aberto:

FreeOnTerminate := True;



GOSTEI 0
Chapolin

Chapolin

09/09/2006

Ok, vou colocar esse código!

muito obrigado, e fica a dica pro pessoal que quizer usar esse esquema interessante

abraço!


GOSTEI 0
Macario

Macario

09/09/2006

Ola.

Posso fazer uso dessa rotina para executar uma SP no MSSQL2000 via dbexpress?

[]´s


GOSTEI 0
POSTAR