Lock de registro

7 views
Skip to first unread message

José Henrique

unread,
Apr 1, 2009, 9:00:52 AM4/1/09
to Infra - Integrated Frameworks
Gostaria de saber como o Infra faz a validação do objeto que será
persistido, ou seja um user_01 carregou um objeto TCliente.oid = 001 e
o user_02 carregou o mesmo TCliente.oid=001, e o user_02 faz uma
alteração numa propriedade do TCliente.DataNascimento ( o cara ficou
sabendo que nasceu noutro dia ....) e o user_02 salva o
TCliente.oid=001 e pronto.

Agora pergunto: Se o user_01 colocar o TCliente.oid=001 em edição
(lembre-se o objeto já havia sido recuperado do banco já faz tempo) ,
e alterar a propriedade TCliente.Nome por exemplo, quando ele for
salvar irá salvar com o valor da propriedade TCliente.DataNascimento
antigo (sem a alteração feita pelo user_02), criando uma
inconsistência nos dados do cadastro.

O Infra faz validação dos estados das propriedades quando vai salvar
um registro? (estilo ClientDataSet?)
O Infra faz lock do registro para que não tenha esse tipo de problema?
Ativo o lock e o registro nao pode ser alterado por nenhum outro
user .
Existe alguma outra maneira de se evitar esse tipo de ocorrência?

Marcos Barreto

unread,
Apr 1, 2009, 12:43:22 PM4/1/09
to infra...@googlegroups.com
Gostaria de saber como o Infra faz a validação do objeto que será
persistido, ou seja um user_01 carregou um objeto TCliente.oid = 001 e
o user_02 carregou o mesmo TCliente.oid=001,  e o user_02 faz uma
alteração numa propriedade do TCliente.DataNascimento ( o cara ficou
sabendo que nasceu noutro dia ....) e o user_02 salva o
TCliente.oid=001  e pronto.

Atualmente a última gravação é a que prevalece. Ainda nao foi definido nenhum tipo de travamento para persistência.
 
Agora pergunto: Se o user_01 colocar o TCliente.oid=001 em edição
(lembre-se o objeto já havia sido recuperado do banco já faz tempo) ,
e alterar a propriedade TCliente.Nome por exemplo, quando ele for
salvar irá salvar com o valor da propriedade TCliente.DataNascimento
antigo (sem a alteração feita pelo user_02), criando uma
inconsistência nos dados do cadastro.

Uma coisa que tenho visto o pessoal fazer quando precisa deste tipo de travamento é colocar um campo data com a data da ultima alteração, assim no where vc pode solicitar a atualização passando esta data no where, se a quantidade de registros afetados foi zero é por que alguem já gravou o registro durante sua edição.
 
O Infra faz validação dos estados das propriedades quando vai salvar
um registro? (estilo ClientDataSet?)

Não, o infra assim como hibernate e outros frameworks por ai nao tratam isso. Mas vamos montar um gerador dinamico de sql que poderá gravar apenas os atributos modificados.
 
O Infra faz lock do registro para que não tenha esse tipo de problema?
Ativo o lock e o registro nao pode ser alterado por nenhum outro
user .
Existe alguma outra maneira de se evitar esse tipo de ocorrência?

Bem se vc souber como vc pode fazer isso até usando clientdataset normal vc fala pra gente. por que acho que nem o delphi usando datasnap tem isso. acho que para fazer lock pessimista vc tem de fazer a leitura usando um tipo de transação própria e então ninguem poderá pegar este registro para gravação, somente como leitura.

vitor rubio

unread,
Apr 1, 2009, 2:29:10 PM4/1/09
to infra...@googlegroups.com
Eu acho que isso independe do infraOPF, porque, me avise se eu estiver errado, as proprias ferramentas padrões do delphi, para se trabalhar no modo RAD, como clientdataset, ibdataset, sqldataset entre outros não trata isso. O client dataset até tem um esquema de verificar alterações, ou deadlock no banco, reconcile error e talz. mas na maior parte das vezes apenas propaga as excessões já ocorridas internamente, disparadas pelo banco.


acho que isso vai depender do modo de transação que você escolher. Tanto no Zeos como no dbXpress e ibXpress vc pode escolher o tipo de transação. Isso é configurado no infra?




Bom, uma sugestão para a persistencia:

para cada coluna do registro o infra poderia ter o new e o old? (me avise se eu estiver viajando, pls)
logo que o infra carregasse um registro do banco de dados, cliente, por exemplo, o nome do cliente iria para a propriedade correspondente, tipo "nome", ao mesmo tempo que iria ser carregado para dois objetos identicos a ele mesmo, o new e o old.


antes de salvar o registro o infra consultaria pelo mesmo registro no banco de dados para trazer as informações mais atualizadas possivel e adotar uma estratégia de merge. Por exemplo, se você alterou nome e data de nascimento, mas outro usuario alterou sobrenome e fantasia antes de você salvar, o que poderia ser feito era o seguinte: 
1) Tudo o que o usuario alterar vai para o new.
2) antes de salvar, trazer o registro do banco de dados por cima do atual, daí compara cada um dos registros do new e do old, e o que for diferente entre os dois joga por cima do atual, que já vai estar com sobrenome e fantasia diferentes do old e do new. Assim você não sobrescreve o atual alterado pelo outro usuario com valores antigos que estavam no seu new.(recebendo agora os novos nome e data de nascimento) . Depois de feito o merge você persiste o atual.

Pode fazer o merge em cima do new e persistir o new tambem. é uma ideia.


2009/4/1 Marcos Barreto <mrba...@gmail.com>



--
Vitor
       Luiz
               Rubio ^^

Joao Morais

unread,
Apr 1, 2009, 4:14:10 PM4/1/09
to infra...@googlegroups.com
2009/4/1 Marcos Barreto <mrba...@gmail.com>:

>> O Infra faz lock do registro para que não tenha esse tipo de problema?
>> Ativo o lock e o registro nao pode ser alterado por nenhum outro
>> user .
>> Existe alguma outra maneira de se evitar esse tipo de ocorrência?
>
> Bem se vc souber como vc pode fazer isso até usando clientdataset normal vc
> fala pra gente. por que acho que nem o delphi usando datasnap tem isso.

O método Press de fazer isto é colocar um campo updatecount em cada
tabela. A cada alteração esse update é atualizado para mais um, e a
cada update um 'and updatecount=n' é acrescentado a clausula where
para evitar alterar um objeto já alterado. De resto é conforme o
Marcos colocou na mensagem original.

Um plus para essa abordagem é: caso o updatecount seja diferente, lê
os campos alterados no BO e compara o seu 'old' com o que tem no
banco. Igual? Continua a gravação. Diferente? Ergue uma exceção.

> acho
> que para fazer lock pessimista vc tem de fazer a leitura usando um tipo de
> transação própria e então ninguem poderá pegar este registro para gravação,
> somente como leitura.

Lock pessimista? Foge disso exceto se você souber exatamente o que e
porque você está fazendo.

Joao Morais

Marcos Barreto

unread,
Apr 1, 2009, 9:22:43 PM4/1/09
to infra...@googlegroups.com
É isso ai mesmo pessoal!
Reply all
Reply to author
Forward
0 new messages