Curso de dbExpress e DataSnap

Parte XIV – Cache BDE x Cachê ClientDataSet

Neste exemplo vamos estudar um pouco sobre o mecanismo de cache do ClientDataSet. Aproveitarei para fazer alguns comparativos com o mecanismo de cache do BDE, para aqueles que estão migrando de solução. Ou seja, a aplicação que preparei é um comparativo entre o mecanismo de cache do BDE (Cache Updates) e a cache (Data) do ClientDataSet.

Configure uma conexão dbExpress para o banco EMPLOYEE do Interbase. Coloque um SQLConnection apontando para essa conexão. Coloque também um SQLQuery, um DataSetProvider, um ClientDataSet, um DataSource, dois DBGrids e dois Buttons. Da mesma forma, configure um acesso BDE para o mesmo banco de dados. Os componentes são: DataBase, Query, UpdateSQL e DataSource. Configure-os como mostrado na listagem a seguir:

 

  object DBGrid1: TDBGrid

    DataSource = DataSource1

  end

  object DBGrid2: TDBGrid

    DataSource = DataSource2

  end

  object SQLConnection1: TSQLConnection

    ConnectionName = 'EMPLOYEE'

    DriverName = 'Interbase'

    GetDriverFunc = 'getSQLDriverINTERBASE'

    LibraryName = 'dbexpint.dll'

    LoginPrompt = False

    Params.Strings = (

      'DriverName=Interbase'

      'Database=C:\Borland\InterBase\examples\database\employee.gdb'

      'RoleName=RoleName'

      'User_Name=sysdba'

      'Password=masterkey'

      'ServerCharSet='

      'SQLDialect=3'

      'BlobSize=-1'

      'CommitRetain=False'

      'WaitOnLocks=True'

      'ErrorResourceFile='

      'LocaleCode=0000'

      'Interbase TransIsolation=ReadCommited'

      'Trim Char=False')

    VendorLib = 'gds32.dll'

  end

  object SQLQuery1: TSQLQuery

    SQL.Strings = (

      'select * from CUSTOMER')

    SQLConnection = SQLConnection1

  end

  object DataSource1: TDataSource

    DataSet = ClientDataSet1

  end

  object Database1: TDatabase

    DatabaseName = 'LOCAL'

    DriverName = 'INTRBASE'

    LoginPrompt = False

    Params.Strings = (

      'SERVER NAME=IB_SERVER:/PATH/DATABASE.GDB'

      'USER NAME=SYSDBA'

      'OPEN MODE=READ/WRITE'

      'SCHEMA CACHE SIZE=8'

      'LANGDRIVER='

      'SQLQRYMODE='

      'SQLPASSTHRU MODE=SHARED AUTOCOMMIT'

      'SCHEMA CACHE TIME=-1'

      'MAX ROWS=-1'

      'BATCH COUNT=200'

      'ENABLE SCHEMA CACHE=FALSE'

      'SCHEMA CACHE DIR='

      'ENABLE BCD=FALSE'

      'BLOBS TO CACHE=64'

      'BLOB SIZE=32'

      'WAIT ON LOCKS=FALSE'

      'COMMIT RETAIN=FALSE'

      'ROLE NAME='

      'PASSWORD=masterkey')

    SessionName = 'Default'

  end

  object Query1: TQuery

    CachedUpdates = True

    DatabaseName = 'LOCAL'

    SQL.Strings = (

      'select * from CUSTOMER')

    UpdateObject = UpdateSQL1

  end

  object UpdateSQL1: TUpdateSQL

  end

  object DataSetProvider1: TDataSetProvider

    DataSet = SQLQuery1

  end

  object ClientDataSet1: TClientDataSet

    ProviderName = 'DataSetProvider1'

  end

  object DataSource2: TDataSource

    DataSet = Query1

  end

 

Seu formulário deve estar semelhante ao mostrado a seguir:

image001.png 

Figura 1.

Para ver como a cache funciona em ambos os engines, criei um método que adiciona 5 mil registros em um DataSet passado como parâmetro. Ele gera valores strings randomizados para cada ccampo da tabela:

 

procedure TFrmMain.AppendRandomRecords(DataSet: TDataSet);

var

  i : integer;

begin

  DataSet.Open;

  for i := 1 to 5000 do

  begin

    DataSet.Append;

    DataSet.FieldByName('CUST_NO').AsInteger := I;

    DataSet.FieldByName('CUSTOMER').AsString := RandomStr;

    DataSet.FieldByName('CONTACT_FIRST').AsString := RandomStr;

    DataSet.FieldByName('CONTACT_LAST').AsString := RandomStr;

    DataSet.FieldByName('ADDRESS_LINE1').AsString := RandomStr;

    DataSet.FieldByName('ADDRESS_LINE2').AsString := RandomStr;

    DataSet.FieldByName('STATE_PROVINCE').AsString := RandomStr;

    DataSet.POST;

    Application.ProcessMessages;

  end;

end;

 

No botão Iniciar de cada engine, chamamos o método passando o respectivo DataSet (Query do BDE ou ClientDataSet do DataSnap):

 

procedure TFrmMain.BitBtn1Click(Sender: TObject);

begin

  AppendRandomRecords(ClientDataSet1);

end;

 

procedure TFrmMain.BitBtn2Click(Sender: TObject);

begin

   AppendRandomRecords(Query1);

end;

 

Após iniciar a inserção de registros aleatórios, observe que a aplicação consome mais memória (Task Manager) quando se usa o CDS. Isso comprova que todas as alterações e updates ficam no processo da aplicação, em memória.

 image003.png

Figura 2.

 image005.png

Figura 3.

No BDE, são criados arquivos no disco (veja dir. atual da aplicação) para armazenar as atualizações, como comprova a figura a seguir.

 image007.png

Figura 4.

image009.png 

Figura 5.

Com isso, vemos que o DataSnap usa um mecanismo de cache muito mais inteligente e efetivo. Aplicações com DataSnap serão bem mais escaláveis e rápidas. O BDE não foi feito e não está preparado para a criação de soluções desse tipo, deficiência que foi suprida pelo dbExpress e ClientDataSet.

 

Download

Você pode fazer download de todos os exemplos deste curso a partir do endereço http://cc.borland.com/Author.aspx?ID=222668. É preciso fazer o cadastro na BDN, que é gratuito e pode ser feito a partir do endereço http://bdn.borland.com

 

dbExpress, DataSnap e ClientDataSet: Técnicas Avançadas

Para mais informações sobre acesso a dados no Delphi e técnicas avançadas, sugiro a leitura do meu livro, “Delphi: Programação para Banco de Dados e Web”, como apoio para o aprendizado das tecnologias. Na obra mostro várias técnicas introdutórios e avançadas de desenvolvimento com ClientDataSet, dbExpress e DataSnap (multicamadas, incluindo SOAP e COM+). Para mais informações, consulte o link http://www.clubedelphi.net/guinther

 

 

Leia todos artigos da série