banco access x cliente / servidor

Delphi

05/09/2003

Srs,

Estou desenvolvendo uma pequena aplicação e por armazenar poucos dados, optei por desenvolvê-la em usando como banco de dados, o Access. A minha dúvida é a seguinte: Criei o banco de dados e o disponibilizei no servidor, então quando a minha aplicação estiver rodando nas estações, como será a atualização dos dados nestas estações, ou seja eu estou logado em uma estação e alterando um registro no cadastro de clientes, quando é que esta alteração estará disponível para o outro usuário da rede que irá por exemplo fazer uma consulta aos dados que eu acabei de alterar? Qual é o tempo de refresh do banco? Como controlar o uso exclusivo do registro para evitar que 2 usuários alterem o mesmo registro ao mesmo tempo?

Os bancos de dados em geral ( incluindo o access) tratam estas situações, ou o programador tem que criar as rotinas necessárias para este controle?


Programalista

Programalista

Curtidas 0

Respostas

Mmtoor

Mmtoor

05/09/2003

Prezado colega:
Gostaria de colocar uma explanação menor, mas os seus questionamentos não permitiriam isso.
Assim sendo, informo que, uma aplicação que permite o acesso multiusuário a uma tabela corre um sério risco: o de dois ou mais usuários simultaneamente editarem o mesmo registro, sem que um siaba que o outro está editando.
Com Paradox, o Delphi bloqueia o registro que está sendo editado, impedindo que outro usuário o edite enquanto a modificação está sendo feita. É um bloqueio pessimista. O registro só é desbloqueado quando o usuário grava a modificação.
Já o Access trabalha de modo diferente. Dois usuários podem editar o mesmo registro simultaneamente. Mas se um deles salvar a modificação feita, o outro não poderá mais salvar as suas modificações. É um bloqueio otimista.
Uma mensagem será apresentada, ou seja, o access alerta que o registro foi modificado por outro usuário, quando vc tenta gravar o registro cuja imagem não corresponda mais a realidade.
Após receber esta mensagem você deve cancelar a edição feita, chamando o método cancel do componente table.
Quando vc cancela a edição, automaticamente a tabela é relida, e as modificações feitas pelo outro usuário aparecem em seu registro.
Observe que você só é alertado na primeira vez que tenta gravar um registro que foi modificado sem vc saber. Se, após a mensagem, vc tentar salvar suas modificações, irá conseguir.
A messagem de erro mencionada que será apresentada estará em inglês, e, infelizmente ainda nos dias de hoje, a maioria dos usuários e operadores de computador não conhecem este idiioma.
Assim sendo, cabe fazer um tratamento nesta mensagem no evento OnPostError do objeto table ou query utilizado. Este evento ocorre sempre que um erro aparece ao editarmos a tabela e possui a seguinte síntase:
OnPostError(DataSet: TdataSet; E: EdataBaseError;varAction:TdataAction);
O parâmetro E é um objeto da classe EdataBaseError, ou seja, equivale à exceção gerada. Toda classe de exceções possui propriedades e métodos comuns, entre eles a propriedade Message, que determina a mensagem a ser apresentada, do tipo string.
Portanto, para modificarmos a mensagem oferecida quando ocorre um erro na tentativa de gravação de um registro modificado, basta digitarmos o seguinte código:

Procedure Tform1.Table1PostError(DataSet: TdataSet; E: EdataBaseError; var Action: TdataAction);
Begin
E.Message:= ‘Registro modificado por outro usuário! Sua edição será cancelada e o registro atualizado!’;
Table1.cancel;
End;

Aproveitamos então para chamar o método cancel do componente table.

Você também deve proporcionar em sua aplicação a oportunidade do usuário reler os dados do registro, sempre que desejar.
Para isso, conforme vc mesmo já colocou, utilize o método refresh do componente table ou query.
Este método relê o registro, colocando nos componentes de visualização de dados os valores atuais.
O mais interessante que a releitura destes dados seja realizada de forma automática.
Esta automatização de refresh pode ser feita com um Ttimer.
Um cuidado deve ser tomado neste evento. A releitura dos dados se dá através do método refresh, só que ele aciona o método post, gravando na tabela o que esta sendo editado, ou seja, se vc estiver editando um registro e, de tempos em tempos o método refresh é chamado, as modificações são salvas imediatamente, quer vc queira ou não, o que não é nenhum pouco conveniente.
Para impedir, ou seja, contornar isso, usamos a função DBIIsRecordLocked, da API do BDE. Esta função verifica se o registro está bloqueado. Se estiver, ou seja, se vc estiver editando-o, o método refresh não é chamado para sua máquina.
Esta função não funciona para as outras máquinas que não estão editando o registro, portanto, elas executarão o método refresh normalmente.
A função DBIIsRecordLocked possui dois parâmetros. O primeiro refere-se à propriedade Handle da tabela, e o segundo a uma variável booleana que armazena o resultado da função.
Se o registro estiver bloqueado, a variável booleana retornará True.
Você deve acrescentar a unit BDE na cláusula Uses da seção Interface para poder utilizar a função DBIIsRecordLocked.
Para colocar isso em prática, coloquemos um timer no form (se quiser implementar pode inserir também um label). Um intervalo razoável para o timert seria de 5000 (5 segundos).
No evento Ontimer insira o seguinte código (não se esquecendo de adicionar a unit BDE na cláusula Uses da seção Interface).
Procedure Tform1.Timer1.Timer(Sender : Object);
Var
Editando: bool;
Begin
DBIIsRecordLocked(Table1.Handle, editando);
If editando = False Then
Begin
Table1.refresh;
Label1.Caption:= ‘Dados atualizados em ‘+TimerToStr(Now);
End;
End;

Obs: Caso, na abertura do seu sistema haja muita latência haverá uma mensagem de erro pois o evento refresh será chamado e a tabela ainda não estará aberta. Basta clicar em OK e prosseguir, ou, se preferir, aumentar o tempo para refresh;

Devo informar ao colega que. Mesmo com todos estes cuidados ainda pode haver necessidade de mais tratamentos.

Espero ter ajudado.
MMTOOR2003


GOSTEI 0
Programalista

Programalista

05/09/2003

Caro colega,

Vc postou uma verdadeira aula sobre acessos ao banco de dados Access, agradeço a sua atenção, e somente agora eu começo a perceber a importância de saber qual o banco de dados utilizar para uma aplicação, posso ver então que o access não é um banco de dados assim tão seguro para ser usado por multiusuários. Como estou começando a trilhar os caminhos do delphi, esta informação é para mim de grande valor.

Agradeço mais uma vez.


GOSTEI 0
Mmtoor

Mmtoor

05/09/2003

Prezado colega:
Só gostaria de salientar que o access pode ser usado sim e, dependendo do seu projeto, ele atenderá todas as necessidades de seu sistema.
Muito vale o projeto que será feito [u:7cf6311acb]antes do desenvolvimento[/u:7cf6311acb].
Saiba que, mesmo que seja utilizado um banco tipo Interbase, MySQL, SQL, ou outro qualquer, se não houver um bom projeto não haverá um bom sistema, certo.
MMTOOR2003


GOSTEI 0
POSTAR