Editorial. Editorial. Dúvidas Correspondência ou fax com dúvidas devem ser enviados ao - THE CLUB, indicando "Suporte".



Documentos relacionados
ArpPrintServer. Sistema de Gerenciamento de Impressão By Netsource Rev: 02

Memória Flash. PdP. Autor: Tiago Lone Nível: Básico Criação: 11/12/2005 Última versão: 18/12/2006. Pesquisa e Desenvolvimento de Produtos

CRIANDO BANCOS DE DADOS NO SQL SERVER 2008 R2 COM O SQL SERVER MANAGEMENT STUDIO

CONFIGURAÇÃO DE REDE SISTEMA IDEAGRI - FAQ CONCEITOS GERAIS

Despachante Express - Software para o despachante documentalista veicular DESPACHANTE EXPRESS MANUAL DO USUÁRIO VERSÃO 1.1

Guia Site Empresarial

MANUAL DE UTILIZAÇÃO

SISTEMAS OPERACIONAIS LIVRES. Professor Carlos Muniz

Procedimentos para Reinstalação do Sisloc

Dicas para usar melhor o Word 2007

1 REQUISITOS BÁSICOS PARA INSTALAR O SMS PC REMOTO

Manual do Google agenda. criação e compartilhamento de agendas

Manual Integra S_Line

3. No painel da direita, dê um clique com o botão direito do mouse em qualquer espaço livre (área em branco).

Configurando o IIS no Server 2003

Noções de. Microsoft SQL Server. Microsoft SQL Server

Sistema de Chamados Protega

Listando itens em ComboBox e gravando os dados no Banco de Dados MySQL.

Manual de Atualização Versão

Manual Captura S_Line

CONFIGURAÇÃO MINIMA EXIGIDA:

SUMÁRIO 1. AULA 6 ENDEREÇAMENTO IP:... 2

Cadastramento de Computadores. Manual do Usuário

UNIVERSIDADE FEDERAL DE GOIÁS CERCOMP (CENTRO DE RECURSOS COMPUTACIONAIS) TUTORIAL DE USO DO WEBMAIL - UFG

FERRAMENTAS DE COLABORAÇÃO CORPORATIVA

Manual do Instar Mail v2.0

Manual do sistema SMARsa Web

MANUAL DE CONFIGURAÇÃO DO BACKUP

Desenvolvendo Websites com PHP

Entendendo como funciona o NAT

Sumário 1. SOBRE O NFGoiana DESKTOP Apresentação Informações do sistema Acessando o NFGoiana Desktop

Fox Gerenciador de Sistemas

COMPARTILHAMENTO DO DISCO E PERMISSÕES DE REDE PÚBLICAS E DE GRUPOS DE TRABALHO.

Data Transformation Services (DTS) por Anderson Ferreira Souza

Operações de Caixa. Versão 2.0. Manual destinado à implantadores, técnicos do suporte e usuários finais

CONSTRUÇÃO DE BLOG COM O BLOGGER

INSTALAÇÃO DO SISTEMA CONTROLGÁS

ETEC DR. EMÍLIO HENRNANDEZ AGUILAR PROGRAMAÇÃO DE COMPUTADORES II PROFESSOR RAFAEL BARRETO DELPHI FORMULÁRIO COM ABAS E BUSCAS DE REGISTROS

Configurando um Grupo Doméstico e Compartilhando arquivos no Windows 7

MANUAL DO USUÁRIO SORE Sistema Online de Reservas de Equipamento. Toledo PR. Versão Atualização 26/01/2009 Depto de TI - FASUL Página 1

SCPIWeb. SCPIWebDespRec Aplicação Web para Consulta de Despesas e Receitas ( Lei Complementar nº 131 de 27 Maio de 2009 )

Satélite. Manual de instalação e configuração. CENPECT Informática cenpect@cenpect.com.br

Índice: CMS 3 O que é Content Management System? Clientes 4 O que é o Cliente? 4 Configurando o i-menu/i-view para trabalhar. com o CMS.

Operador de Computador. Informática Básica

MANUAL DO ANIMAIL Terti Software

Revisão: Introdução. - Integração com o AutoManager; 1 Atualização de versão do banco de dados PostgreSQL

10 DICAS DE TECNOLOGIA PARA AUMENTAR SUA PRODUTIVIDADE NO TRABALHO

Iniciação à Informática

Google Drive: Acesse e organize seus arquivos

02 - Usando o SiteMaster - Informações importantes

Está apto a utilizar o sistema, o usuário que tenha conhecimentos básicos de informática e navegação na internet.

Manual de Utilização

Banco de Dados Microsoft Access: Criar tabelas. Vitor Valerio de Souza Campos

Versão Liberada. Gerpos Sistemas Ltda. Av. Jones dos Santos Neves, nº 160/174

O sistema está pedindo que eu faça meu login novamente e diz que minha sessão expirou. O que isso significa?

MANUAL DO GERENCIADOR ESCOLAR WEB

Como instalar uma impressora?

FAÇA FÁCIL: DRIVER IGS PARA COMUNICAÇÃO DE PROTOCOLOS PROPRIETÁRIOS INTRODUÇÃO

SUMÁRIO Acesso ao sistema... 2 Atendente... 3

Manual de Instalação ProJuris8

Programação Orientada a Objetos com PHP & MySQL Cookies e Sessões. Prof. MSc. Hugo Souza

MANUAL TISS Versão

Banco de Dados Microsoft Access: Criar tabelas

Microsoft Access: Criar consultas para um novo banco de dados. Vitor Valerio de Souza Campos

Solicitação de Manutenção de Veículo. Manual SRM

SSE 3.0 Guia Rápido Parametrizando o SISTEMA DE SECRETARIA Nesta Edição Configurando a Conexão com o Banco de Dados

Entrar neste site/arquivo e estudar esse aplicativo Prof. Ricardo César de Carvalho

1 Sumário O Easy Chat Conceitos Perfil Categoria Instalação O Aplicativo HTML...

Atualizaça o do Maker

Escaneando seu computador com o Avira AntiVir 10

Manual do Sistema "Vida Controle de Contatos" Editorial Brazil Informatica

Manual das funcionalidades Webmail AASP

Manual SAGe Versão 1.2 (a partir da versão )

Instalando o Internet Information Services no Windows XP

Microsoft Access: Criar relações para um novo banco de dados. Vitor Valerio de Souza Campos

CAPÍTULO 8 Conexões de banco de dados para programadores ASP.NET

NetEye Guia de Instalação

Como medir a velocidade da Internet?

1. Escritório Virtual Atualização do sistema Instalação e ativação do sistema de Conexão...5

Registro e Acompanhamento de Chamados

1- Requisitos mínimos. 2- Instalando o Acesso Full. 3- Iniciando o Acesso Full pela primeira vez

TUTORIAL COMO CRIAR E EDITAR UM VÍDEO NO WINDOWS MOVIE MAKER*

OneDrive: saiba como usar a nuvem da Microsoft

MANUAL DE INSTALAÇÃO 1) ORACLE VIRTUALBOX ; 2) MICROSOFT WINDOWS ; 3) SUMÁRIOS GENEPLUS.

Orientação a Objetos

Comm5 Tecnologia Manual de utilização da família MI. Manual de Utilização. Família MI

ETEC DR. EMÍLIO HENRNANDEZ AGUILAR PROGRAMAÇÃO DE COMPUTADORES I PROFESSOR RAFAEL BARRETO

BH PARK Software de Estacionamento

Vamos criar uma nova Página chamada Serviços. Clique em Adicionar Nova.

Bem- Vindo ao manual de instruções do ECO Editor de COnteúdo.

Unidade 7: Panes no Excel

Guia de Início Rápido

Instalando software MÉDICO Online no servidor

Sistema de Instalação e Criação da Estrutura do Banco de Dados MANUAL DO INSTALADOR. Julho/2007. Ministério da saúde

V.1.0 SIAPAS. Sistema Integrado de Administração ao Plano de Assistência à Saúde. Contas Médicas

Dicas Satux. Adicionando uma Impressora. Configurando o Primeiro acesso. Adicionar/Remover Programas. Como fazer gravações de CD/DVD

Manual do usuário. Mobile Auto Download

Kerio Exchange Migration Tool

Transcrição:

Editorial Editorial THE CLUB Av. Profº Celso Ferreira da Silva, 190 Jd. Europa - Avaré - SP - CEP 18.707-150 Informações: (14) 3732-3689 Suporte: (14) 3733-1588 - Fax: (14) 3732-0987 Internet http://www.theclub.com.br Cadastro: cadastro@theclub.com.br Suporte: suporte@theclub.com.br Informações: info@theclub.com.br Dúvidas Correspondência ou fax com dúvidas devem ser enviados ao - THE CLUB, indicando "Suporte". Opinião Se você quer dar a sua opinião sobre o clube em geral, mande a sua correspondência para a seção "Tire sua dúvida". Reprodução A utilização, reprodução, apropriação, armazenamento em banco de dados, sob qualquer forma ou meio, de textos, fotos e outras criações intelectuais em cada publicação da revista The Club Megazine são terminantemente proibidos sem autorização escrita dos titulares dos direitos autorais. Impressão e acabamento: GRAFILAR Tel.: (14) 3841-2587 - Fax: (14) 3841-3346 Rua Cel. Amando Simôes, 779 Cep 18.650-000 - São Manuel - SP Tiragem: 5.000 exemplares Copyright The Club Megazine 2005 Diretor Técnico Mauro Sant Anna Colaboradores Mário Bohm, Márcio Alexandroni Delphi é marca registrada da Borland International, as demais marcas citadas são registradas pelos seus respectivos proprietários. Olá amigos, Estamos aqui com mais uma The Club Megazine! Começamos esta edição com algumas dicas que serão bem proveitosas no seu dia-a-dia, confira... Nosso consultor Claudinei Rodrigues preparou um artigo sobre um recurso muito utilizado no Windows, ou seja, arrastar e soltar, ou se preferir: Drag and Drop, veja como implementar em suas aplicações Delphi. Continuando, trataremos de um tema bastante interessante aos usuários de Firebird, onde demonstramos algumas configurações que podem garantir maior estabilidade a este ótimo banco de dados com ajustes no TCP/IP. E, dando continuidade na série de artigos sobre Visual Studio.NET e Oracle, o melhor de dois mundos, nosso amigo Mário Bohm demonstra como gerar código automaticamente com o Oracle e a Developer Tools For.NET. Atendendo um gama de solicitações, Márcio Alexandroni do ClubePDA explana sobre qual a melhor ferramenta para desenvolver para PalmOS e PocketPC, se você têm dúvida a respeito, não deixe de conferir este artigo. Nosso consultor Alessandro Ferreira preparou um artigo onde demonstra como efetuar tratamento de erros em aplicações que utilizam a dbexpress como camada de acesso a banco de dados, conheça alguns macetes bem legais a este respeito. Partindo para o mundo.net, publicamos 10 dicas bem quentes que irão lhe auxiliar a extrair o máximo de performance em aplicações ASP.NET. E finalizando, compartilhamos algumas das perguntas que chegaram até nossos consultores neste último mês através de nossa sessão Perguntas & Respostas. Abraço e sucesso à todos, Editorial... 03 Dicas & Truques... 04 Trabalhando com Drag in Drop no Delphi... 06 Usando KEEPALIVE-sockets para detectar e liberar conexões do InterBase e Firebird travadas, ou como prevenir o erro 10054/104... 08 Gerando Código Automaticamente com o Oracle Developer Tools for.net... 12 Qual a melhor ferramenta para desenvolver para PalmOS e PocketPC?... 14 dbexpress: Tratamento Centralizado de Erros... 16 ASP.NET 10 dicas para escrever aplicações Web de alta performance... 20 Perguntas & Respostas... 27 3

Dicas & Truques Windows Como verificar quantidade de memória utilizada Nesta dica iremos demonstrar como verificar a quantidade de memória utilizada (em bytes) por sua aplicação Delphi, fazendo uso das APIs para controle de processos disponibilizadas na unit PsAPI. implementation uses psapi; {$R *.dfm} function GetProcessMemorySize(_sProcessName: string; var _nmemsize: Cardinal): Boolean; var l_nwndhandle, l_nprocid, l_ntmphandle: HWND; l_ppmc: PPROCESS_MEMORY_COUNTERS; l_ppmcsize: Cardinal; l_nwndhandle := FindWindow(nil, PChar(_sProcessName)); if l_nwndhandle = 0 then Result := False; Exit; l_ppmcsize := SizeOf(PROCESS_MEMORY_COUNTERS); GetMem(l_pPMC, l_ppmcsize); l_ppmc^.cb := l_ppmcsize; GetWindowThreadProcessId (l_nwndhandle, @l_nprocid); l_ntmphandle := OpenProcess (PROCESS_ALL_ACCESS,False, l_nprocid); if (GetProcessMemoryInfo (l_ntmphandle, l_ppmc, l_ppmcsize)) then _nmemsize := l_ppmc^.workingsetsize else _nmemsize := 0; FreeMem(l_pPMC); Result := True; // Exemplo de chamada: procedure TForm1.Button1Click(Sender: TObject); var l_nsize: Cardinal; if (GetProcessMemorySize(Application. Title, l_nsize)) then ShowMessage( Quantidade de memória utilizada: + 4

Dicas & Truques FormatFloat( ###,###,###,###, l_nsize) + bytes ) else ShowMessage( Não consegui obter a memória utilizada. ); Neste exemplo estamos verificando a quantidade de memória utilizada pela própria aplicação, ou seja, informamos como parâmetro no nome do processo Application.Title, contudo, caso necessite verificar outros processos bastará informar o nome do mesmo como parâmetro da função GetProcessMemorySize. Windows Verificar FAT32 ou NTFS Esta dica demonstra como verificar se uma partição (unidade de disco) está utilizando sistema de arquivos FAT32 ou NTFS. function GetHardDiskPartitionType(const DriveLetter: Char): string; // FAT // NTFS var NotUsed: DWORD; VolumeFlags: DWORD; VolumeInfo: array[0..max_path] of Char; VolumeSerialNumber: DWORD; PartitionType: array[0..32] of Char; GetVolumeInformation(PChar(DriveLetter + :\ ), nil, SizeOf(VolumeInfo), @VolumeSerialNumber, NotUsed, VolumeFlags, PartitionType, 32); Result := PartitionType; // Exemplo de chamada: procedure TForm1.Button1Click(Sender: TObject); ShowMessage(GetHardDiskPartitionType( c )); ShowMessage(GetHardDiskPartitionType( d )); DBExpress - Arredondamento de Valores Incorretos Quando atribuímos um cálculo para um campo reconhecido como TFMTBcdField na dbexpress (com várias casas decimais) ele pode arredondar incorretamente. Para resolver é necessário efetuar a atribuição como BCD assim: uses FMTBcd; var A,L,C,X : Extended; Sender.AsFloat := (StrToFloat(text)); A := (cdsembalagemm3_altura.asfloat/1000); L := (cdsembalagemm3_largura.asfloat/1000); C := (Sender.AsFloat/1000); cdsembalagemfatorm3.asbcd := DoubleToBCD(A * L * C); INNOSETUP Como Verificar se uma Chave Existe no Registro do Windows Aqui trazemos mais uma dica deste fantástico gerador de instalações, onde demonstramos como verificar se uma determinada chave existe no registro do Windows: [Setup] AppName=VerificaChave AppVerName=VerificaChave DefaultDirName={pf}\VerificaChave DisableStartupPrompt=true Uninstallable=false DisableDirPage=true OutputBaseFilename=VerificaChave [Code] function InitializeSetup(): Boolean; if RegKeyExists(HKEY_LOCAL_MACHINE, SOFTWARE\Firebird Project\Firebird Server ) then MsgBox( Não posso instalar!, mbinformation, MB_OK ); Result := false; end else Result := true; Isso é muito interessante, por exemplo, para verificar se uma determinada aplicação já existe no computador do cliente. 5

Delphi Trabalhando com Drag in Drop no Delphi Por Claudinei Rodrigues nei@theclub.com.br Devido à natureza gráfica de Windows a maioria das operações pode ser executada unicamente com o mouse. Uma operação que é frequentemente útil para o usuário é poder arrastar um objeto de uma posição a outra. No Delphi isto é algo muito fácil de se fazer. Vamos ver como fazer isto. Trabalhando com eventos Nós vamos trabalhar com dois eventos, são eles: OnDragDrop OnDragOver Agora vamos ver detalhadamente cada um deles: OnDragDrop Este evento é disparado sempre quando um item é solto sobre outro componente. A maioria do código necessário para implementar o Drag and Drop é implementado neste evento. Este evento recebe alguns parâmetros. Veja-os a seguir: Sender -> Este parâmetro é o objeto que recebeu o objeto que foi solto. Source -> Este é o ponteiro para o item atual que está sendo arrastado e solto. Por exemplo, se for um item de um ListBox que está sendo arrastado, este parâmetro aponta para o Listbox e não para o texto atual que está sendo arrastado. X,Y -> Estas são as coordenadas relativas de onde o objeto foi arrastado no objeto. OnDragOver Este evento é disparado sempre quando um item é arrastado sobre outro componente. Seu uso principal é decidir se o item pode ser solto sobre o componente e mudar o cursor para refletir se isto é ou não possível. Os parâmetros usados são os seguintes: Sender, Source -> Representam a mesma informação do evento OnDragDrop. X,Y -> Representam a mesma informação do evento OnDragDrop. Accept -> Este parâmetro deve ser ajustado para True se o controle que é o arrastado atualmente puder ser aceito. State -> Este parâmetro diz se a operação foi correta, movendo o objeto. Montando um exemplo Com base nestas informações vamos montar um exemplo. Neste exemplo nós teremos dois componentes Listbox em um formulário e vamos mostrar como é fácil permitir que o usuário arraste os itens de um componente Listbox para outro componente Listbox, e reposicione também os itens em cada Listbox arrastando e deixando cair os itens selecionados. 1 - Chame o seu Delphi e crie uma nova aplicação. 2 Inclua dois componentes Listbox neste form. O componente Listbox está disponível na palheta Standard 3 Em cada um dos componentes Listbox, vá até a propriedade DragMode e altere-a para dmautomatic. Fazendo isto nós estamos informando ao componente que não precisaremos iniciar a operação de arrasto manualmente. Agora nós vamos gerar os eventos OnDragOver e OnDragDrop de um componente ListBox e configurar os eventos correspondentes do outro Listbox. Para isto vamos trabalhar agora com o código fonte. 1 Clique no componente ListBox1, pressione a tecla F11. Fazendo isto o Object Inspector será ativado. Agora clique na aba Events e vá até evento OnDragOver e dê um duplo clique. Neste evento você deve incluir o código que está dentro do bloco... end mostrado a seguir: procedure TForm1.ListBox1DragOver (Sender, Source: TObject; X, Y: Integer; State: TDragState; var Accept: Boolean); if Source is TListBox then Accept := True; 2 Agora nós vamos configurar o objeto que foi solto para que seja atualizado no seu destino. Isto é feito no evento OnDragDrop. Para isto acesse o evento OnDragDrog e inclua o código abaixo: procedure TForm1.ListBox1DragDrop (Sender, Source: TObject; X, Y: Integer); var Temp : integer; Temp1 : TPoint; Temp2 : String; //Aqui estamos obtendo as coordenadas X e Y // do item Temp1.x := x; Temp1.y := y; 6

Delphi Temp := 0; //Aqui estamos montando um laço para permitir // que os itens possam ser movidos While Temp <= TListBox(Source). Items.Count-1 do // Aqui pegamos o item que desejamos mover, // ouseja, aquele que está selecionado. if TListBox(Source).selected[Temp] then With Sender as TListBox do // Neste ponto nós precisamos utilizar uma // variável temporária, pois quando o item // for removido o indice mudará. Temp2 := TListBox(Source).items[Temp]; TListBox(Source).items.Delete(Temp); items.insert(itematpos(temp1,true), Temp2); inc(temp); Agora vá até o componente ListBox2 e ligue os eventos OnDragOver e OnDragDrop aos mesmos eventos do componente ListBox1. E não esqueça de incluir alguns itens aos componentes Listbox. Feito isto basta compilar o projeto, clicar sobre os Listbox e arrastar os itens. Conclusão. Este foi um artigo direcionado a alguns sócios que estavam precisando deste recurso, então eu achei melhor publicar este artigo que com certeza irá auxiliar muito mais pessoas. Arquivo para download em: http://www.theclub.com.br/ revista/download/dd0905.zip Sobre o autor Claudinei Rodrigues, Consultor Técnico do The Club nei@theclub.com.br 7

Firebird/Interbase Usando KEEPALIVE-sockets para detectar e liberar conexões do InterBase e Firebird travadas, ou como prevenir o erro 10054/104 Introdução Nos sistemas com banco de dados Interbase ou Firebird, os quais tem intenção de trabalhar em modo de tempo real ou próximo disso, há um problema com o status do rastreamento das conexões do cliente no lado do servidor, e isso força a desconexão quando no caso do cliente se tornar inacessível por causa de uma liberação da conexão. É importante liberar rapidamente os recursos ocupados com estas conexões fantasmas, especialmente quando se usa servidores com estrutura clássica. Se muitos usuários se conectam ao servidor através de conexões por modem instáveis, o de desconexão se torna extremamente alto. Por exemplo, um cliente salva um record set alterado, e após o UPDATE ser executado (enquanto o COMMIT ainda não foi) a conexão cai. Como regra, a aplicação cliente em tais situações se reconectará ao servidor, mas o cliente (como ele/ela ainda continua trabalhando com os dados, mesmo após salvar receberá uma mensagem de erro por causa da falha de conexão) não será capaz de salvar as mudanças, uma vez que ele/ela receberá uma mensagem de conflito de travamento ( lock conflict on update ). A conexão anterior, que abriu a transação (no contexto da qual o UPDATE foi executado, enquanto o COMMIT não foi), ainda guarda os registros. A falha de conexão talvez ocorra em redes locais também, se o hardware (placas de rede, hubs, comutadores) estão com problemas ou mal conectados, e/ou por causa de interferências na rede. Nos logs do Firebird e do Interbase, falhas de conexão com o protocolo TCP são mostradas com o erro 10054 no Windows e 104 no Unix, falhas do netbeui são mostradas como erros 108/109. Métodos de controle de travamento de conexões No Interbase e no Firebird, os mecanismos de DUMMYpackets ou KEEPALIVE-sockets são usados para rastrear e desabilitar tais conexões mortas. No Interbase 5.0 ou mais recente, o mecanismo de DUMMYpackets foi implementado como uma camada da aplicação entre o servidor Firebird/Interbase e o cliente gds/fbclient. Isto está incluído no ibconfig/firebird.conf e não será examinado neste artigo. Obs: Como sabemos por experiências anteriores, a estabilidade do mecanismo de dummy-packets (o que foi implementado no Interbase 5.0 e corrigido no Firebird 1.5x) depende fortemente dos sistemas operacionais do servidor e do cliente, versão do stack do tcp e muitas outras condições. Pode-se dizer que, a efetividade de tal sistema numa rede real tende a zero. O KEEPALIVES-packets é um mecanismo mais interessante. Implementado no Interbase 6.0 ou mais recente, tem como propósito rastrear falhas de conexão. O KEEPALIVE é habilitado ajustando a opção SO_KEEPALIVE na abertura. Não há necessidade de fazer isso manualmente se você está usando o Firebird 1.5x ou mais recente, já que ele foi implementado no código de programação do Firebird Server, para o Classic e Superserver. Para as versões do Interbase e Firebird mais antigas, há uma variação com a estrutura clássica, assim é necessário um ajuste adicional. Este ajuste é descrito abaixo. Neste caso, o tcp stack do sistema operacional (ao invés do 8

Firebird/Interbase Firebird Server) se torna responsável pelo status da conexão. No entanto, para habilitar este mecanismo, deve-se ajustar os parâmetros do KEEPALIVE. Descrição do KEEPALIVE. O comportamento do KEEPALIVE-sockets é controlado pelo parâmetro presente na tabela seguinte. O tcp stack rastreia o momento que os pacotes param de transmitir entre o cliente e o servidor, executando um timer do KEEPALIVE. Tão logo o timer chegue no ponto do KEEPALIVE_TIME, o servidor do tcp stack executará a primeira sonda do KEEPALIVE. A sonda é um pacote vazio com um flag ACK que é enviado para o usuário. Se estiver tudo bem no lado do cliente, então o tcp stack do lado do cliente envia um pacote de resposta com um flag ACK, e o servidor de tcp stack reajusta o timer do KEEPALIVE assim que ele recebe uma resposta. Se o cliente não responde à sonda, as sondagens do servidor continuam a ser enviadas. A quantidade delas é igual à do valor KEEPALIVE_PROBES, elas são executadas pelo intervalo definido no KEEPALIVE_INTERVAL. Se o cliente não responde à última sonda, então após outro período do KEEPALIVE_INTERVAL expirar, o tcp stack do sistema operacional fecha a conexão, e o servidor (neste caso, uma instância do Firebird ou Interbase) libera todos os recursos ocupados com esta conexão. Assim, uma conexão do cliente que falhou será fechada após o seguinte período de intervalo: KEEPALIVE_TIME+ (KEEPALIVE_PROBES+1) * KEEPALIVE_INTERVAL. Por padrão, os valores dos parâmetros são muito grandes, isso os torna ineficazes. Por exemplo, o valor padrão do parâmetro KEEPALIVE_TIME é 2 horas, tanto em Linux como em Windows. Certamente, 1 ou 2 minutos seria o suficiente para tomar uma decisão sobre uma desconexão forçada de um cliente inacessível. Por outro lado, o padrão do KEEPALIVE causa desconexões forçadas em redes Windows, que estão inativas durante estas duas horas. Abaixo estão os ajustes destes parâmetros para Windows e Linux. Ajustando o KEEPALIVE no Linux Os parâmetros do KEEPALIVE no Linux podem ser alterados diretamente por edição dos arquivos de sistema ou chamando o sysctl. Para o primeiro caso, as seguintes linhas devem ser editadas: /proc/sys/net/ipv4/tcp_keepalive_time /proc/sys/net/ipv4/tcp_keepalive_intvl /proc/sys/net/ipv4/tcp_keepalive_probes Para o segundo caso, os seguintes comandos devem ser executados: sysctl w net.ipv4.tcp_keepalive_time=value sysctl w net.ipv4.tcp_keepalive_intvl=value sysctl w net.ipv4.tcp_keepalive_probes=value O valor está expresso em segundos. Para o ajuste automático destes parâmetros no caso da reinicialização do servidor, adicione as seguintes linhas ao /etc/ sysctl.conf: net.ipv4.tcp_keepalive_intvl = value net.ipv4.tcp_keepalive_time = value net.ipv4.tcp_keepalive_probes = value Substitua <value> pelos valores apropriados. Se você está usando uma versão anterior do Firebird 1.5x, então deve-se adicionar o seguinte no /etc/xinet.d/firebird: FLAGS=REUSE KEEPALIVE Ajustando o KEEPALIVE no Windows 95/98 e ME Seção do registro HKEY_ LOCAL_ MACHINE\System\ CurrentControlSet\Services\VxD\MSTCP Tudo sobre os ajustes do TCP podem ser encontrados aqui: http://support.microsoft.com/default.aspx?scid=kb;enus;158474 Parâmetros: * KeepAliveTime = milisegundos Tipo: DWORD 9

Firebird/Interbase Para Windows 98 tipo STRING. Define o tempo de inatividade da conexão em milisegundos. Quando ele expira, as sondas do KEEPALIVE começam a ser executadas. O valor padrão é 2 horas (7200000). * KeepAliveInterval = valor de 32-digitos Tipo: DWORD Para Windows 98 tipo STRING. Define o tempo entre as sondas do KEEPALIVE em milisegundos. Tão logo o intervalo KeepAliveTime expire, após cada período do KeepAliveInterval (em milisegundos), as sondas do KEEPALIVE são enviadas até o número máximo de MaxDataRetries. Se não houver resposta, a conexão se fecha. O valor padrão é 1 segundo (1000). * MaxDataRetries = valor de 32 dígitos Tipo: STRING Define o número máximo de sondas do KEEPALIVE. O valor padrão é 5. Ajustando o KEEPALIVE no Windows NT/2000/XP Seção do registro: HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\ Services\Tcpip\Parameters\. Tudo sobre os ajustes de TCP: 2000/ NT: http://support.microsoft.com/kb/120642 XP: http://support.microsoft.com/kb/314053 O parâmetro MaxDataRetries foi substituído por TCPMaxDataRetransmissions. Todos os outros parâmetros tem o mesmo nome do Windows 9x. Ajustando o KEEPALIVE nos clientes Windows Este ajuste é opcional, mas provavelmente reduzirá o número de mensagens de falhas de conexão se o usuário não tiver um canal de comunicação confiável. Insira nesta seção do registro: HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\ Services\Tcpip\Parameters Parâmetro DisableDHCPMediaSense = 1. Veja uma descrição deste parâmetro aqui: http://support.microsoft.com/?scid=kb%3bru%3b239924&x=13&y=14 Exemplo Vamos considerar o ajuste do Firebird 1.5.2 para o sistema operacional Linux. * Tenha certeza que o mecanismo de DUMMY-packets estão desabilitados no firebird.conf.... # DummyPacketsInterval = 0... * Tenha certeza que é o arquivo de configuração /etc/sinet.d/ firebird Vamos manter tudo sem mudanças, como está desde a instalação. Nada será adicionado. * Mudança dos parâmetros do TCP stack sysctl w net.ipv4.tcp_keepalive_time = 15 sysctl w net.ipv4.tcp_keepalive_intvl = 10 sysctl w net.ipv4.tcp_keepalive_probes = 5 * Conecte-se à qualquer banco de dados no servidor de qualquer cliente de rede. * Cheque o tráfego no servidor usando um filtro de pacotes. Se o parâmetro estiver especificado como /proc/sys/net/ tcp_keepalive_*, com 15 segundos após tudo parar no canal, o servidor cria uma sonda. Se o cliente estiver vivo ( alive ), o servidor recebe um pacote de resposta. 15 segundos após isto, a checagem se repete, e assim por diante. * Se o cliente está fisicamente desligado (ou se o multiplexador ou o modem são desligados repentinamente tudo é possível), então o servidor não receberá uma resposta, e o servidor começará a enviar sondas com 10 segundos de intervalo. Se o cliente não responder à quinta sonda, então 10 segundos após isto, o servidor faz uma descarga, e libera os recursos que estão bloqueando os travamentos. Se o cliente der algum sinal e responder pelo menos à quinta sonda (se o que está ruim piorar), então, após outros 15 segundos de time-out, o servidor começará a enviar sondas. E assim por diante. Conclusões Concluindo, quero dar alguns conselhos sobre como os 10

Firebird/Interbase valores do KEEPALIVE devem ser usados. Primeiramente, determine o valor necessário do KEEPALIVE_TIME. Somente após este valor é que as sondas do KEEPALIVE serão lançadas. Se você ver constantemente erros 10054/104 no log do servidor, e você tiver que deletar isto manualmente, é recomendável que você aumente o valor de KEEPALIVE_TIME. Segundo, os valores de KEEPALIVE_INTERVAL e KEEPALIVE_PROBES devem ser suficientes para satisfazer suas necessidades antes de já existirem conexões travadas. Se os clientes se conectarem ao servidor através de conexões não confiáveis, então você deve aumentar o número de sondas o intervalo entre elas, para dar ao usuário uma chance de detectar o problema e se conectar ao servidor. No caso de clientes que usam conexões de banda larga à Internet, ou acessam o SQL através de uma rede local, é possível diminuir o valor de tempo entre as sondas. Recomendações gerais: Se você não tem razões particulares para receber muitas mensagens de erro dos clientes, a respeito dos resultados de gravação, por causa dos conflitos de travamento (não há conexões concorrentes trabalhando com os mesmos dados), então você precisa aumentar a reação do sistema para liberar as conexões travadas. Praticamente, o valor de KEEPALIVE_TIME deve ser acima ou igual a 1 minuto. Você mesmo deve determinar qual o maior tempo de uma transação, para que o tráfego não fique sobrecarregado por checagens do KEEPALIVE em conexões de trabalho normais, que lançam grandes transações. O valor de KEEPALIVE_INTERVAL deve ser maior ou igual a 10 segundos, e o de KEEPALIVE_PROBES igual ou maior que 5. Quando muitos usuários trabalham simultaneamente, lembre-se que se você ficar checando periodicamente, pode haver um aumento no tráfego de rede. Lembre-se também que, caso seus usuários mudem os mesmos dados frequentemente, erros de travamento acontecerão como resultado da situação. Neste caso, você precisa tratar este erro na aplicação. Ao mesmo tempo, a aplicação deve ser capaz de minimizar tais erros. Exemplos de configuração padrão Finalmente, aqui estão mais alguns exemplos de configuração. Downtime é o tempo que os usuários não são capazes de atualizar os dados (que é o momento da atualização da transação aberta até a conexão travada). Total time é o tempo de expiração que a conexão travada será fechada. KEEPALIVE_TIME 1 minutes KEEPALIVE_PROBES 3 KEEPALIVE_INTERVAL 30 seconds TOTAL 3 minutes * Clientes que usam conexão de rede; muitas das transações são curtas; downtime é limitado em 2 minutos KEEPALIVE_TIME 30 sec KEEPALIVE_PROBES 5 KEEPALIVE_INTERVAL 10 sec TOTAL 90 seconds * Clientes que usam qualquer conexão; downtime não é definido KEEPALIVE_TIME 15 minutes KEEPALIVE_PROBES 4 KEEPALIVE_INTERVAL 1 minutes TOTAL 20 minutes * Clientes que usam qualquer conexão, transações contínuas são possíveis no sistema, e o downtime limite é 15 minutos KEEPALIVE_TIME12 minutes KEEPALIVE_PROBES 7 KEEPALIVE_INTERVAL 15 sec TOTAL 14 minutes Espero que estes exemplos que mostrei sejam suficientes para um ajuste correto do TCP stack do mecanismo do KEEPALIVE. 11

Oracle Utiizando VS.NET com DATA PROVIDER Oracle... Parte 3 Gerando Código Automaticamente com o Oracle Developer Tools for.net por Mário Camilo Bohm Como foi apresentado nos últimos artigos, o ORACLE DEVELOPER TOOLS FOR VISUAL STUDIO.NET oferece diversas ferramentas para o dia-a-dia do desenvolvedor, trazendo para dentro do Visual Studio todo o poder do Oracle, e pode ser encontrado em: http://www.oracle.com/technology/tech/dotnet/index.html Dando continuidade ao assunto, veremos neste artigo como utilizar esta ferramenta para acessar o Oracle em um projeto simples em C#. Para criarmos o nosso exemplo, crie um novo projeto no Visual Studio.net (Menu File>New> Project) e escolha o tipo Visual C# Projects e o template Windows Application, adicionando o nome desejado. Utilizando o Oracle Exporer ( para maiores informações sobre o Oracle Explorer consulte a primeira e a segunda parte deste artigo, ou visite a url mencionada acima...) Selecione a tabela que deseja consultar e arraste-a para o formulário. Clique sim para salvar a senha da conexão: Note que após este passo, serão gerados automaticamente os objetos ADO.Net para manipulação da Tabela, estes objetos utilizam o que há de mais otimizado para acesso ao Oracle apartir do.net, o Oracle Data Provider for.net. Pressione F7 para acesar o código e note que foram criados os objetos ADO.Net especiais para acesso ao Oracle. 12

datagrid1.datasource = ds.tables[0]; Conforme figura : Oracle A partir da Aba Toolbox do Visual Studio.Net adicione um objeto DataGrid ao seu Form, arrastando-o e soltando no local desejado conforme figura: Pronto!, agora com apenas 3 linhas de código já conseguiremos popular o Grid com os Dados da Tabela. Escreveremos nosso código no construtor do formulário, ou seja o método de mesmo nome que o form (ou classe) em seu código, por exemplo, caso o form tenha o nome de Form1 o construtor será parecido com o seguinte : public Form1() { // Required for Windows Form Designer support // InitializeComponent(); // // TODO: Add any constructor code after //InitializeComponent call // } Adicione o seguinte código logo abaixo de InitializeComponent(); : DataSet ds= new DataSet(); nomedasuatabelaoracledataadapter1.fill(ds); A primeira linha cria um objeto do tipo DataSet que será carregado com os dados, a segunda linha usa o objeto OracleDataAdapter criado automaticamente quando arrastamos a tabela, para preencher o DataSet, note que este objeto terá o nome de sua tabela mais o complemento OracleDataAdapter1 por default portanto substitua nomedasuatabela do código pelo nome da tabela que está utilizando. A terceira linha diz que o DataGrid da página deve ser preenchido com a tabela que acabamos de carregar no objeto DataSet. Para maiores informações sobre estes objetos do ADO.Net consulte : http://msdn.microsoft.com/ Para testar o projeto pressione F5 : Pronto, com apenas 3 linhas de código acessamos uma tabela do Oracle a partir de uma aplicação Windows em C#.Net, isto porque boa parte dos códigos necessários para este acesso foram gerados automaticamente quando arrastamos a tabela para o formulários, existem muitas outras formas de acessarmos o Oracle usando os objetos fornecidos pelo Oracle Provider for.net, neste artigo apenas demonstramos uma forma simples e rápida de trabalhar com estes objetos usando o Visual Studio.net com o Oracle Explorer Installado. Para conhecer maiores detalhes sobre as ferramentas da Oracle para.net visite: http://www.oracle.com/technology/tech/dotnet/index.html 13

PocketPC Qual a melhor ferramenta para desenvolver para PalmOS e PocketPC? por Márcio Alexandroni Essa é sem dúvida a pergunta mais postada em todos os newsgroups que participo e por isso resolvi escrever esse artigo para expor minha opinião a respeito. Para começar, é preciso mencionar que as plataformas móveis até hoje não têm recursos excepcionais de processamento, armazenamento e sincronismo; eu costumo comparar as plataformas móveis nos cursos e palestras que ministro com os PCs que trabalhávamos no início da década de 90, ou seja, sem HD, com dois drives de 5 ¼ de densidade simples. Um aparte: não sou tão velho assim, comecei ainda no berço a trabalhar com a informática... Outro assunto muito comum em listas de discussão e nos cursos diz respeito à comparação entre as plataformas móveis, PalmOS x PocketPC. São duas plataformas distintas, PalmOS continua visando a simplicidade de operação e os equipamentos até o PalmOS 5 ainda são monousuários; o que promete ser diferente no Cobalt, mas a PalmSource também havia prometido esse recurso no PalmOS 5. Vamos esperar para ver os equipamentos que serão lançados mais para o final do ano. O PocketPC teve desde a sua concepção, um sistema operacional mais parecido com seu pai, o Windows para desktops, multitarefa, multimídia, processadores mais velozes, mais expansões, etc, mas na minha opinião, a Microsoft errou muito nas primeiras versões, pois tinham os mesmos problemas do sei pai para o desktop, problemas de gerenciamento de memória principalmente. Até o Windows CE 3.0, que equipava aqui no Brasil a série HP Jornada 7XX, os sistemas operacionais eram praticamente reescritos à cada versão e como as ferramentas disponíveis na época não tinham grandes recursos, era muito comum uma aplicação não funcionar mais na versão superior do sistema operacional, forçando o desenvolvedor a mudar a aplicação ou recompila-la para a nova versão do sistema operacional. Já na plataforma PalmOS, as novas versões sempre garantiam a total compatibilidade de executável, ou seja, uma aplicação desenvolvida para o PalmOS 4 não precisa ser recompilada, roda sem alterações no PalmOS 5 e também roda no Emulador do Cobalt (PalmOS 6). Isso garante que os investimentos feitos pelo desenvolvedor no aprendizado de uma ferramenta e também no desenvolvimento de uma aplicação sejam mantidos. O sistema operacional PocketPC hoje é muito mais robusto e teve uma grande reformulação e uma grande implementação: o.net Compact Framework. O.NET Framework foi uma grande revolução na maneira dos desenvolvedores escreverem aplicações para Windows e Web e agora também podem utilizar uma parte do conjunto de classes do.net Framework para o PocketPC. De imediato, isso garante que uma aplicação tenha portabilidade para qualquer tipo de máquina PocketPC, não importa o processador, pois o Framework compila a aplicação para o processador destino na primeira vez que ela é executada na máquina, garantindo a melhor performance para a aplicação e adaptação à máquina que está sendo executada. Também garante o funcionamento em versões futuras do PocketPC. Off-topic: como exemplo, há hoje uma implementação do.net Framework até para Linux, pelo projeto Mono, www.go-mono.com. Depois dessa introdução, voltamos a falar sobre ferramentas. Costumo dizer que não existe a melhor ferramenta para desenvolver, mas existem opções e recursos que devem ser considerados: 1) Se as plataformas móveis ainda não têm poder de processamento, armazenamento e sincronismo, é importante que 14

PocketPC uma ferramenta possa tirar o maior e melhor proveito da plataforma, utilizando todos os recursos disponíveis pelo processador e sistema operacional. 2) É importante que a ferramenta possa gerar um código que garanta a sua utilização em versões futuras do sistema operacional, não tornando o código obsoleto quando uma nova versão do sistema operacional é liberada. Visando as importantes características acima, temos dois grandes grupos de ferramentas: - As que suportam todos os recursos do sistema operacional, portanto tem garantia de suportar os itens 1 e 2 acima; - As que têm runtime e geram executáveis interpretados e que dependem de atualização do fabricante para que possam funcionar plenamente na nova versão do sistema operacional. Para PalmOS, as ferramentas que suportam nativamente os recursos do sistema operacional e geram executáveis sem runtime são: CodeWarrior, PocketStudio, GCC (compilador free baseado em C/C++ que não tem IDE, mas existem IDEs para adquirir no mercado) e HB++. Destas ferramentas, eu utilizo CodeWarrior para construir bibliotecas como meus produtos SyncAnywhere, GraphLib, etc, e para desenvolver aplicações, uso PocketStudio, pois dá maior produtividade e gera código bem próximo ao código gerado pelo CodeWarrior. Já usei o GCC, mas achei o código um pouco maior e mais lento e nunca utilizei HB++ pelo fato da ferramenta ter preço em EUROS, o que a torna um pouco cara para os padrões brasileiros. No PalmOS, as ferramentas mais utilizadas que têm runtime são NSBasic, Satellite Forms, Java (J2ME e SuperWaba) e AppForge/MobileVB. Não há nada contra qualquer uma dessas ferramentas, desde que atenda às necessidades do desenvolvedor para seu projeto específico, principalmente no que diz ao suporte aos recursos do equipamento e necessidades dos clientes. Para PocketPC, há ferramentas como o MobileVB, Satellite Forms, NSBasic e o pacote Visual Studio.NET 2003 da Microsoft, que já liberou a versão Beta do Visual Studio.NET 2005. Neste segmento, a única ferramenta que realmente utiliza o.net Compact Framework é o pacote da Microsoft. Outras virão, o Delphi 9 por exemplo, promete gerar código.net Compact Framework, mas isso ainda não é oficial, depende do suporte da Borland ao produto da Microsoft. Na minha opinião, utilizar o.net Compact Framework hoje é o objetivo principal para qualquer ferramenta, pois somente os códigos gerados nesta plataforma terão total garantia de funcionamento em versões futuras do PocketPC. Existem ferramentas que geram código para ambas plataformas, PalmOS e PocketPC, são ferramentas com runtime. Eu não utilizo nenhuma ferramenta neste segmento, pois se dá suporte às duas plataformas, que são totalmente diferentes, dá suporte a apenas uma parte dos recursos de cada uma delas. O desenvolvedor deve fazer testes com essas ferramentas para garantir que elas realmente terão o suporte que o seu produto necessita. O exemplo mais comum para comparar ferramentas é: você desenvolveu um sistema de Automação de Força de Vendas e inicialmente seu sincronismo de dados é local (HotSync ou ActiveSync). Seu cliente solicita sincronismo via FTP, o que o obrigará a utilizar uma biblioteca externa para esse fim ou precisará utilizar a API ou classes do sistema operacional e desenvolver uma rotina específica. A ferramenta escolhida suporta essa necessidade? Vamos supor que mais adiante seu cliente precise que a aplicação acesse remotamente um banco de dados relacional ou trabalhe em um ambiente WiFi. A ferramenta escolhida suporta essa tecnologia? Conclusão: minha resposta à pergunta deste artigo é sempre a mesma: não existe a melhor ferramenta para desenvolver, há ferramentas mais poderosas e as que têm desenvolvimento mais rápido, mas a escolha final é sempre do desenvolvedor em função da sua necessidade e do seu cliente. Eu sempre sugiro ferramentas que possam tirar proveito de todos os recursos que as plataformas móveis dispõem, mas dependendo da aplicação e do tempo que o desenvolvedor tem para colocar uma aplicação no mercado, sua escolha pode variar dentro das opções disponíveis e da sua experiência em desenvolvimento. Aviso importante: O ClubePalm está comercializando apostilas/cd em português para desenvolvimento em PocketStudio. Você que é associado do The Club tem vantagem na aquisição deste kit. Ao adquirir o kit você ganhará 5% de desconto, basta informar o código THECLUB2005. Lembrando que teremos treinamento em PocketStudio de 18 a 20 de outubro no Rio de Janeiro, para maiores informações acesse: www.clubepda.com.br/cursos.asp. Sobre o autor Márcio Alexandroni ClubePDA A referência do desenvolvedor PDA. www.clubepda.com.br 15

Delphi dbexpress: Tratamento Centralizado de Erros por Alessandro Ferreira, alessandro@theclub.com.br Introdução Neste artigo irei abordar um tema muito solicitado aqui no suporte The Club, ou seja, como implementar um tratamento de erros trabalhando com o dbexpress e consequentemente com o ClientDataSet, onde demonstraremos como tratar erros no lado cliente e também erros providos pelo servidor de banco de dados. Tratando erros no cliente Quando menciono: tratamento de erros no cliente, refiro-me ao fato de efetuar validações antes mesmo do registro ser postado ao banco de dados, com isso, evita-se o tráfego em rede e conseqüentemente temos uma resposta mais rápida à repassar ao usuário. Um ótimo local para efetuarmos este tipo de validação é o evento OnPostError do componente ClientDataSet, visto o mesmo ser acionado automaticamente mediante qualquer violação verificável pelo ClientDataSet. A fim de economizar código, podemos implementar uma função genérica e chamar esta função dentro do OnPostError e com isso, caso haja necessidade de alguma alteração ou nova validação, bastará alterar esta função que o evento irá tratar os erros com base nas novas regras definidas. Na listagem 1, apresento um código simples que utilizo no evento OnPostError dos ClientDataSet de meus aplicativos: function CommonPostError(DataSet: TDataSet; E: EDatabaseError): TDataAction; var Msg: String; Msg := E.Message; if Pos( MUST HAVE A VALUE, UpperCase(E.Message)) > 0 then Msg := Copy(Copy(E.Message,Pos(,E.Message)+1, Length(E.Message)),1,Pos(,Copy(E.Message, Pos(,E.Message)+1,Length(E.Message)))-1); Msg := Format( O campo %s deve ser preenchido!, [Msg]); end else if Pos( KEY VIOLATION, UpperCase(E.Message)) > 0 then Msg := Format( Registro duplicado em %s, [DataSet.Name]); end else if Pos( FIELD VALUE REQUIRED, UpperCase(E.Message)) > 0 then Msg := Format( Existem campos obrigatórios não preenchidos, verifique!, [DataSet.Name]); ShowMessage(Msg); Result := daabort; Listagem 1 - Função CommonPostError Na listagem 2, demonstro como utilizar a função CommonPostError no evento OnPostError de um ClientDataSet: 16

Delphi procedure TfmCadCanais.cdsCanaisPostError (DataSet: TDataSet; E: EDatabaseError; var Action: TDataAction); Action := CommonPostError(DataSet, E); Listagem 2. Observe que o evento OnPostError possui três parâmetros: DataSet = Representa o componente ClientDataSet em edição. E = Traz as informações a respeito do erro, como por exemplo, a mensagem de erro. Action = Qual a ação que será tomada mediante o erro ocasionado, podendo receber como valor: dafail : Aborta a operação e apresenta a mensagem de erro. daabort : Aborta a operação e não apresenta a mensagem de erro. daretry : Repere a operação. Em nossa função estamos utilizando como retorno daabort, pois iremos abortar a operação e apresentar uma mensagem personalizada e não a mensagem original de erro sugerida pelo EDatabaseError. Um outro aspecto importante, é que a classe EDatabaseError não retorna um código de erro e sim somente a mensagem de erro e, será com base na mensagem de erro que iremos personalizar a informação à ser repassada ao usuário, como exemplo: este método e algum erro de validação ocorrer no servidor, nenhuma exceção será levantada e os dados não serão efetivados no banco de dados. Você pode estar se perguntando o por que disso e achando até um pouco estranho. Na realidade, como é de conhecimento de todos, o ApplyUpdates recebe um parâmetro do tipo inteiro, o qual muita gente utiliza sem saber exatamente sua finalidade. Este parâmetro indica o número máximo de erros suportados durante o processo de atualização, visto que, devido ao mecanismo de cache, você pode ter N registros em memória e efetuar apenas um ApplyUpdates para confirmar todo o processamento. Dentro deste contexto, qual o valor correto à ser informado ao ApplyUpdates? Isso irá depender de suas necessidades! Vamos expor algumas situações: a. Supondo que você possua N registros em cache e no momento da atualização necessite que: todos os registros sejam gravados com sucesso ou do contrário, nenhum deles seja efetivado no banco de dados, o valor a ser informado será 0, ou seja, você não admite nenhum erro no processo de atualização. b. Supondo que você possua N registros em cache e estes registros não tenham nenhum tipo de integridade entre si e deseje gravar o que conseguir, ficando apenas os registros com problemas no cache, o valor a ser informado será -1. Como mencionei anteriormente, se alguma violação ocorrer durante o processo de atualização, nenhuma exceção será levantada, visto que o mecanismo Provider/Resolver permite o tratamento de falhas no processo de atualização registro a registro utilizando o evento OnReconcileError do ClientDataSet, dessa forma, qualquer erro que seja gerado neste processo, poderemos verificar através do evento OnReconcileError. Novamente, vamos implementar uma função genérica para tratamento dos erros, confira a listagem 3: Tratando erros retornados pelo Servidor Mesmo efetuando o tratamento de erros no evento OnPostError, existem muitas validações (como exemplo: Integridade Referencial) que são efetuadas no banco de dados e, dessa forma não passam pelo evento OnPostError, lembrando que estes erros serão apresentados apenas após a execução do método ApplyUpdates, visto que até então, os dados estão em cache local no Cliente. Ainda sobre o método ApplyUpdates, gostaria de ressaltar que o mesmo não gera uma exceção, isso mesmo, se você chamar function CustomReconcileError (DataSet: TDataSet; UpdateKind: TUpdateKind; E: EReconcileError): TReconcileAction; const Acao: array [TUpdateKind] of string = ( Alterar, Inserir, Excluir ); var Msg: string; i: Integer; if pos( PK_CLIENTES,E.Message)>0 then 17

Delphi Msg:=Format( Cliente já cadastrado!,[]); if pos( FK_PRODUTO_TRI,E.Message)>0 then Msg:=Format( Tributação está sendo usada por Produto!,[]); case UpdateKind of ukdelete: Result := racancel; ukinsert: Result := raabort; ukmodify: Result := raabort; if Msg= then Msg := Não foi possível completar esta operação, informe a mensagem abaixo ao suporte! #13+E.Message; ShowMessage(Format( Não foi possível %s o registro. +#13+Msg,[Acao[UpdateKind]])); Listagem 3 - Função CustomReconcileError Através da mensagem de erro poderemos personalizar a mensagem apresentada ao usuário, e para isso teremos que analisar a mensagem retornada pelo banco de dados, por isso, torna-se importante nomear as constraints, primary keys, foreign keys, etc existentes em seu banco de dados, pois dessa forma será fácil efetuar o tratamento via Delphi. Na listagem 4, demonstro a chamada da função CustomReconcileError dentro do evento OnReconcileError de um ClientDataSet: procedure TfmCadCanais. cdscanaisreconcileerror (DataSet: TCustomClientDataSet; E: EReconcileError; UpdateKind: TUpdateKind; var Action: TReconcileAction); inherited; Action := CustomReconcileError (DataSet, UpdateKind, E); Listagem 4. O evento OnReconcileError possui quatro parâmetros: Parâmetros do evento OnReconcileError Garantindo atualizações de múltiplos ClientDataSets Os tratamentos de erros efetuados através do evento OnReconcileError geralmente atendem a maioria das necessidades neste contexto, contudo, existem situações peculiares onde não conseguimos garantir a integridade dos dados durante o processo de atualização apenas com base neste evento. Por exemplo, supondo que você possua três componentes ClientDataSet sem nenhum tipo de relacionamento entre eles e necessite que todos os três sejam efetivados no banco de dados com sucesso ou todo o processo seja revertido, em resumo: ou grava tudo ou não grava nada! Neste caso teremos que utilizar um controle de transação para garantir a integridade no processo de atualização, todavia vale lembrar que o método ApplyUpdates não levanta nenhuma exceção... assim sendo, como verificar se houve algum erro sem utilizar o evento OnReconcileError? Bem, o método ApplyUpdates é uma função que retorna o número de erros gerados no processo de atualização e dessa forma ficará fácil implementarmos um tratamento coeso dos dados, confira a listagem 5: procedure SetaTD(var TD: TTransactionDesc); Randomize; TD.TransactionID := Trunc(Random(65635)*Now); TD.IsolationLevel := xilreadcommitted; Var TD: TTransactionDesc; // Configura transação. SetaTD(TD); // Abre transação. 18

Delphi SQLConnection.StartTransaction(TD); // Inicia atualização dos ClientDataSets. Try if ClientDataSet1.ApplyUpdates(0) > 0 then raise Exception.Create ( Erro no 1º ClientDataSet ); if ClientDataSet2.ApplyUpdates(0) > 0 then raise Exception.Create ( Erro no 2º ClientDataSet ); if ClientDataSet3.ApplyUpdates(0) > 0 then raise Exception.Create ( Erro no 3º ClientDataSet ); // Confirma a transação. SQLConnection.Commit(TD); Except SQLConnection.RollBack(TD); ShowMessage ( Não foi possível atualizar! ); End; Listagem 5 - Atualização com controle de transação No caso de ClientDataSets relacionados via Máster/Detail não é necessário efetuar este tipo de tratamento, visto que por estarem relacionados será necessário chamar o método ApplyUpdates apenas do ClientDataSet Máster e dessa forma, se você utilizar como parâmetro 0 (ApplyUpdates(0)) o mecanismo Provider/Resolver irá se encarregar de garantir a integridade dos dados. Reconcile Error Dialog Caso você prefira deixar o tratatamento de erros por conta do usuário (particularmente, eu não arrisco!) o Delphi oferece um formulário padrão para tratamento de erros o qual você poderá estar chamando no evento OnReconcileError de seus ClientDataSets (utilizando a mesma abordagem que citei anteriormente). Para criá-lo, vá ao menu File New Other Dialogs, conforme demonstra a figura 1. Ao selecionar a opção apresentada na figura 1, teremos um formulário idêntifco ao apresentado na figura 2. Salve esta nova unit, com um nome sugestivo, como exemplo: unreconciledialog. Agora, acesse o código fonte deste nova unit e encontrará uma função chamada: HandleReconcileError a qual poderá ser utilizada da mesma forma que a função: CustomReconcileError apresentada anteriormente neste artigo, ou seja, bastará você declarar na lista de units (no uses) de sua unit e depois no evento OnReconcileError de seus ClientDataSets efetuar a chamada como demonstrado na listagem 6: procedure TfmCadCanais.cdsCanaisReconcileError( DataSet: TCustomClientDataSet; E: EReconcileError; UpdateKind: TUpdateKind; var Action: TReconcileAction); inherited; Action := HandleReconcileError(DataSet, UpdateKind, E); Listagem 6. Figura 2 formulário ReconcileErrorDialog. Conclusão Demonstrei neste artigo uma abordagem bastante simples e funcional para tratamento de erros na dbexpress/clientdataset, onde com duas funções você poderá ter o controle centralizado de erros na atualização de dados em sua aplicação. Forte abraço e sucesso à todos. Sobre o autor Figura 1: Reconcile Error Dialog Alessandro Ferreira, Consultor Técnico do The Club alessandro@theclub.com.br 19

ASP.Net ASP.NET 10 dicas para escrever aplicações Web de alta performance Escrever uma aplicação Web com o ASP.NET é incrivelmente fácil. Tão fácil, que muitos desenvolvedores não tem tempo para estruturar suas aplicações para um grande performance. Neste artigo, vou apresentar 10 dicas para escrever aplicações Web de alta performance. Não vou limitar meus comentários às aplicações ASP.NET porque elas são apenas um subconjunto das aplicações Web. Este artigo não é um guia definitivo para um ajuste fino de performance de aplicações Web um livro inteiro poderia facilmente ser escrito sobre isto. Ao invés disso, este artigo é um bom lugar para começar. Se você quer fazer escaladas, deve antes ler um guia e ver os comentários e recomendações das pessoas que já visitaram o local antes. Mas, não importa o quão bom seja o guia, você precisa de experiência em escaladas antes de tentar um desafio particular. Similarmente, você só aprenderá como escrever aplicações Web de alta performance quando você encarar os problemas existentes com suas aplicações e consertar os problemas de performance ou executar um teste intensivo no web site. Você pode pensar em separar a aplicação em camadas lógicas. Você talvez tenha ouvido falar sobre o termo de arquitetura física 3-tier (ou n-tier). Eles são normalmente descritos como padrões que dividem fisicamente as funcionalidades através de processos e/ou hardware. Quando o sistema precisa ser escalável, mais hardware pode ser facilmente adicionado. Aí está, no entanto, um alvo de performance associando processo e máquinas poderosas, que deve ser evitado. Então, sempre que possível, execute as páginas ASP.NET e seus componentes associados juntos na mesma aplicação. Por causa da separação do código e dos limites entre as camadas, o uso de Web services ou remotamente irá diminuir a performance em 20% ou mais. A camada de dados é um animal um pouco diferente já que normalmente há um hardware melhor dedicado para o seu banco de dados. No entanto, o custo de processamento de dados ainda é alto, assim a performance na camada de dados será o primeiro lugar onde veremos como otimizar seu código. Antes de nos aprofundar em consertar os problemas de performance em suas aplicações, tenha certeza do perfil de suas aplicações para entender exatamente onde os problemas estão. Os contadores chave de performance (como os que indicam a porcentagem de tempo gasto com o garbage colection) também são muito úteis para encontrar onde as aplicações estão gastando a maior parte de seu tempo. Assim os lugares onde o tempo é gasto são bem intuitivos. Há dois tipos de aumento de performance descritos neste artigo: grandes otimizações, usando o Cache do ASP.NET por exemplo, e pequenas otimizações que são repetidas. Estas pequenas otimizações são muitas vezes mais interessantes. Você faz uma pequena mudança no código que é chamado milhares e milhares de vezes. Com uma grande otimização, você talvez veja a performance geral dar um grande salto. Com uma pequena, Com uma pequena, você talvez corte alguns milissegundos de cada requisição, mas quando combinando os resultados totais através do dia todo, este resultado por representar algo enorme. Performance na camada de dados Quando se volta ao ajuste fino de performance de uma aplicação, When it comes to performance-tuning an application, há um teste simples que você pode usar para priorizar o seu trabalho: o código acessa o banco de dados? Se sim, com que frequência? Observe que o mesmo teste pode ser aplicado também para o código que usa Web services, mas não vou falar disso neste artigo. 20