ClientDataSet: como gerenciar acesso concorrente?
quando usamos Query o DataSet tem como saber que um determinado registro está sendo editado e tomar as providências caso um outro usuário tente editar o mesmo.
mas quando usamos o ClientDataSet, como vai ser feito este controle já que ele carrega os dados na memória e fecha a conexão?
mas quando usamos o ClientDataSet, como vai ser feito este controle já que ele carrega os dados na memória e fecha a conexão?
Raserafim
Curtidas 0
Respostas
Bruno Belchior
13/01/2006
Não há maneiras (pelo menos diretamente não) para fazer isso, o jeito é implementar o evento [b:2ad98edd77]OnReconcilieError[/b:2ad98edd77] para tomarmos a desição do que e como fazer quando um caso deste acontecer...
GOSTEI 0
Raserafim
13/01/2006
então em uma rede que isso é importante, o ClientDataSet é inviável?
se q não pode ser assim pois este componente é utilizado justamente para aplicações multi-camadas, mas não consegui entender...
se q não pode ser assim pois este componente é utilizado justamente para aplicações multi-camadas, mas não consegui entender...
GOSTEI 0
Vinicius2k
13/01/2006
Colega,
Creio que o que vc deseja fazer chama-se ´Travamento pessimista´. Uma prática muito comum, porém, na maioria das vezes, desnecessária se a questão for analisada com cuidado.
Quando se utiliza bancos de dados Desktop como Paradox, Access, dBase, etc, travar o registro é mais do que uma opção, é uma necessidade, porém, com SGBDs é, quase sempre, desnecessário.
A midas não é capaz de fazer isto. A forma de fazer vai variar de acordo com o SGBD. No Firebird, por exemplo, você precisa executar uma query com a instrução ´FOR UPDATE´ e/ou ´WITH LOCK´:
Nesta execução o(s) registro(s) é/são travado(s) para outros usuários até que a transação que efetou o LOCK seja fechada (commit ou rollback).
Antes de seguir o caminho do travamento pessimista, eu sugiro a leitura deste artigo que, na forma conceitual, é valido para qualquer SGBD, caso o que vc esteja utilizando não seja o FB: http://www.comunidade-firebird.org/cflp/downloads/CFLP_T032.PDF
T+
Creio que o que vc deseja fazer chama-se ´Travamento pessimista´. Uma prática muito comum, porém, na maioria das vezes, desnecessária se a questão for analisada com cuidado.
Quando se utiliza bancos de dados Desktop como Paradox, Access, dBase, etc, travar o registro é mais do que uma opção, é uma necessidade, porém, com SGBDs é, quase sempre, desnecessário.
A midas não é capaz de fazer isto. A forma de fazer vai variar de acordo com o SGBD. No Firebird, por exemplo, você precisa executar uma query com a instrução ´FOR UPDATE´ e/ou ´WITH LOCK´:
/* para uma query que retorna múltiplos registros */ select <CAMPOS> from <TABELA> where <CAMPO> = :parametro for update with lock /* para uma query que retorna apenas um registro */ select <CAMPOS> from <TABELA> where <CAMPO> = :parametro with lock
Nesta execução o(s) registro(s) é/são travado(s) para outros usuários até que a transação que efetou o LOCK seja fechada (commit ou rollback).
Antes de seguir o caminho do travamento pessimista, eu sugiro a leitura deste artigo que, na forma conceitual, é valido para qualquer SGBD, caso o que vc esteja utilizando não seja o FB: http://www.comunidade-firebird.org/cflp/downloads/CFLP_T032.PDF
T+
GOSTEI 0
Raserafim
13/01/2006
humm interessante, vou analisar isto.
então o q aconteceria na seguinte situação:
se eu não me preocupasse com nada disso. e em uma máquina cliente o camarada abrisse o cadastro de clientes em um determinado registro. e em outra máquina abrisse o mesmo cadastro de clientes com o mesmo registro. a primeira máquina alterasse a cidade do cliente, e na segunda alterasse o bairro do cliente. o q aconteceria?
então o q aconteceria na seguinte situação:
se eu não me preocupasse com nada disso. e em uma máquina cliente o camarada abrisse o cadastro de clientes em um determinado registro. e em outra máquina abrisse o mesmo cadastro de clientes com o mesmo registro. a primeira máquina alterasse a cidade do cliente, e na segunda alterasse o bairro do cliente. o q aconteceria?
GOSTEI 0
Marcello
13/01/2006
Testei a situação q vc sugeriu no meu programa e o q ocorreu foi q o cadastro foi atualizado normalmente, sem erros.
No meu caso coloquei no provider a opção upWhereKeyOnly, então mesmo q altere o mesmo campo do cadastro o q vai valer é o último q foi gravado.
Acho muito díficil a situação de dois usuários atualizarem o cadastro do mesmo cliente, e caso isto ocorra o mais provavel é digitar os mesmos dados - endereço, fone, etc.
No meu caso coloquei no provider a opção upWhereKeyOnly, então mesmo q altere o mesmo campo do cadastro o q vai valer é o último q foi gravado.
Acho muito díficil a situação de dois usuários atualizarem o cadastro do mesmo cliente, e caso isto ocorra o mais provavel é digitar os mesmos dados - endereço, fone, etc.
GOSTEI 0
Vinicius2k
13/01/2006
então o q aconteceria na seguinte situação:
se eu não me preocupasse com nada disso. e em uma máquina cliente o camarada abrisse o cadastro de clientes em um determinado registro. e em outra máquina abrisse o mesmo cadastro de clientes com o mesmo registro. a primeira máquina alterasse a cidade do cliente, e na segunda alterasse o bairro do cliente. o q aconteceria?
Depende da configuração do TDataSetProvider. Como o colega Marcello citou com a propriedade ´UpdateMode´ do Provider você pode controlar como ele irá se comportar face a esta situação.
Com ´upWhereAll´ a instrução SQL de UPDATE montada pelo provider irá incluir na cláusula WHERE todos os campos com todos os valores que ele possuia originalmente, consequentemente, só será feita alguma alteração se nenhum dos campos tiverem sido alterados por outro usuário. Com isso a alteração feita pelo primeiro usuário prevalecerá e no evento OnReconcileError do TClientDataSet você terá o erro ´Record changed by another user´, após a tentativa de aplicar as alterações.
Com ´upWhereKeyOnly´ apenas a chave primária é incluída na cláusula WHERE da instrução de UPDATE. Se o primeiro usuário não alterar a chave primária (o que, normalmente, não é permitido por você), as alterações efetuadas pelo segundo usuário serão sobrepostas.
T+
GOSTEI 0