Curso de dbExpress e DataSnap - Parte XV
Veja neste artigo de Guinther Pauli, mais um capítulo do curso de DataSnap e dbExpress. Acesso exclusivo para Assinantes.
Curso de dbExpress e DataSnap
Parte XV – Packet Records
Neste exemplo veremos como usar o recurso de Packet Records do ClientDataSet. Configurando essa propriedade, podemos instruir ao servidor de aplicação que “empacote e envie dados por demanda”. Quando temos um grande select no servidor, podemos instruir ao DataSetProvider que vá enviando essas informações aos poucos, para otimizar o tráfego de dados. È importante notar desde já, que essa abordagem é menos escalável: é necessário manter o cursor e conexão ativos durante todo o processo.
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, um DBGrid, um DBNavigator, um Memo e um SQLMonitor. Para configurar o recurso em tempo de execução, coloque também um RadioGroup, dois CheckBoxes, um SpinEdit.
A listagem a seguir mostra como cada componente foi configurado:
object DBGrid1: TDBGrid
DataSource = DataSource1
end
object DBNavigator1: TDBNavigator
DataSource = DataSource1
end
object SQLConnection1: TSQLConnection
ConnectionName = 'EMPLOYEE'
DriverName = 'Interbase'
GetDriverFunc = 'getSQLDriverINTERBASE'
LibraryName = 'dbexpint.dll'
LoadParamsOnConnect = True
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'
Left = 72
Top = 232
end
object SQLQuery1: TSQLQuery
SQL.Strings = (
'select * from CUSTOMER')
SQLConnection = SQLConnection1
end
object DataSetProvider1: TDataSetProvider
DataSet = SQLQuery1
end
object ClientDataSet1: TClientDataSet
ProviderName = 'DataSetProvider1'
end
object DataSource1: TDataSource
DataSet = ClientDataSet1
end
object SQLMonitor1: TSQLMonitor
SQLConnection = SQLConnection1
end
No botão Refresh verificamos as configurações de tela e configuramos o Packet Records do ClientDataSet:
procedure TFrmMain.BitBtn2Click(Sender: TObject);
begin
Memo1.Lines.Clear;
if CheckBox1.Checked then
ClientDataSet1.PacketRecords := SpinEdit1.Value
else
ClientDataSet1.PacketRecords := -1;
ClientDataSet1.Close;
ClientDataSet1.Open;
end;
No OnChange do SpinEdit também mudamos essa configuração:
procedure TFrmMain.SpinEdit1Change(Sender: TObject);
begin
ClientDataSet1.PacketRecords := SpinEdit1.Value;
end;
No botão GetNextPacket chamamos o método de mesmo nome do ClienDataSet:
procedure TFrmMain.BitBtn1Click(Sender: TObject);
begin
ClientDataSet1.GetNextPacket;
end;
No CheckBox com o nome de FetchOnDemand configuramos a propriedade de mesmo do ClienDataSet:
procedure TFrmMain.CheckBox2Click(Sender: TObject);
begin
BitBtn1.Enabled := not CheckBox2.Checked;
ClientDataSet1.FetchOnDemand := CheckBox2.Checked;
end;
No CheckBox usar PacketRecords fazemos alguns ajustes visuais:
procedure TFrmMain.CheckBox1Click(Sender: TObject);
var
i : integer;
begin
GroupBox1.Enabled := CheckBox1.Checked;
Label1.Enabled := CheckBox1.Checked;
SpinEdit1.Enabled := CheckBox1.Checked;
CheckBox2.Enabled := CheckBox1.Checked;
BitBtn1.Enabled := (CheckBox1.Checked) and not (CheckBox2.Checked);
end;
No evento OnLogTrace do SQLMonitor vamos monitorar a comunicação com o IB/FB para verificar quando e quais comandos estão sendo executados, jogando essas informações para um Memo:
procedure TFrmMain.SQLMonitor1LogTrace(Sender: TObject;
CBInfo: pSQLTRACEDesc);
begin
Memo1.Lines.Add(String(CBInfo.pszTrace));
end;
Vamos executar a aplicação e fazer alguns testes, usando diferentes configurações. Dessa forma, vamos entender exatamente como o PacketRecords funciona.
1 – Sem usar PacketRecords - clique no botão Refresh e veja o comportamento na figura a seguir. Todos os dados retornados pelo Select foram empacotados e jogados na memória (Data) do ClienDataSet. Nenhum recurso do servidor, incluindo conexão e cursor, fica preso. No entanto, o tempo necessário e tráfego de rede usado para transferir o packet é maior.
2 – Usando PacketRecords com FetchOnDemand ativado - clique no botão Refresh e veja o comportamento na figura a seguir. Configuramos o packet size como “3”, o que indica que os registros serão empacotados de 3 em três. O próprio ClientDataSet detecta quando mais registros são necessário e traz por demanda (daí o nome FetchOnDemand). Isso pode acontecer tanto por necessidade do usuário (confirme isso navegando no DBGrid para baixo) ou programaticamente (via chamadas subseqüentes ao método Next). Observe que cada Fetch envolve, lógico, uma chamada ao servidor SQL. A solução é mais otimizada para grandes resultsets, mais vai consumir mais recursos do BD, pois o cursor e conexão ficam presos aguardando novas solicitações de packet.
3 – Usando PacketRecords com FetchOnDemand desativado - clique no botão Refresh e veja o comportamento na figura a seguir. Configuramos o packet size como “3”, o que indica que os registros serão empacotados de 3 em três. A diferença em não usar o FetchOnDemand é que você deve solicitar novos pacotes de dados, através do método GetNextPacket do CDS (fizemos isso no botão). Faça um teste navegando até o último registro do DBGrid, observe que ele “trava” no terceiro. Clicando no botão GetNextPacket, mais três registros serão trazidos. Cada Fetch envolve, lógico, uma chamada ao servidor SQL. A solução é mais otimizada para grandes resultsets, mais vai consumir mais recursos do BD, pois o cursor e conexão ficam presos aguardando novas solicitações de packet.
Download
Leia todos artigos da série
- Curso de dbExpress e DataSnap
- Curso de dbExpress e DataSnap - Parte II
- Curso de dbExpress e DataSnap - Parte III
- Curso de dbExpress e DataSnap - Parte IV
- Curso de dbExpress e DataSnap - Parte V
- Curso de dbExpress e DataSnap - Parte VI
- Curso de dbExpress e DataSnap - Parte VII
- Curso de dbExpress e DataSnap - Parte VIII
- Curso de dbExpress e DataSnap - Parte IX
- Curso de dbExpress e DataSnap - Parte X
- Curso de dbExpress e DataSnap - Parte XI
- Curso de dbExpress e DataSnap - Parte XII
- Curso de dbExpress e DataSnap - Parte XIII
- Curso de dbExpress e DataSnap - Parte XIV
- Curso de dbExpress e DataSnap - Parte XV
- Curso de dbExpress e DataSnap - Parte XVI
- Curso de dbExpress e DataSnap - Parte XVII
- Curso de dbExpress e DataSnap - Parte XVIII
- Curso de dbExpress e DataSnap - Parte XIX
- Curso de dbExpress e DataSnap - Parte XX
- Curso de dbExpress e DataSnap - Parte XXI
- Curso de dbExpress e DataSnap - Parte XXII
- Curso de dbExpress e DataSnap - Parte XXIII
- Curso de dbExpress e DataSnap - Parte XXIV
- Curso de dbExpress e DataSnap - Parte XXV
- Curso de dbExpress e DataSnap - Parte XXVI
- Curso de dbExpress e DataSnap - Parte XXVII
- Curso de dbExpress e DataSnap - Parte XXVIII
- Curso de dbExpress e DataSnap - Parte XXIX
- Curso de dbExpress e DataSnap - Parte XXX
Artigos relacionados
-
Artigo
-
Artigo
-
Artigo
-
Artigo
-
Artigo