Página 2 de 2
Enviado: 14 Set 2007 09:50
por Maligno
janio escreveu:Causaria algum dano grave em um ambiente de rede DESBLOQUEAR o registro antes do DbCommit(), como faço no código abaixo?
Ao desbloquear antes do COMMIT, você tornará disponível um registro que não foi atualizado pelas suas alterações. A partir daí, pense no que pode acontecer.

Enviado: 14 Set 2007 09:57
por Pablo César
Bem observado, essa é um erro que facilmente alguns podem passar por alto. Bem lembrado !. Aparentemente o ´codigo não tem erro mas a sequência deles pode causar falha de atualização no BDs.
Enviado: 14 Set 2007 17:14
por Ademir
Boa tarde a todos !
Sem falar que comecei a ter problemas devido ao uso do Dbcommitall(). Nem pesquisei qual foi a causa. Simplesmente passei a descarregar o buffer uma area de cada vez. O problema acabou.
Enviado: 14 Set 2007 19:14
por janio
Maligno escreveu:Ao desbloquear antes do COMMIT, você tornará disponível um registro que não foi atualizado pelas suas alterações. A partir daí, pense no que pode acontecer.
Mas no exemplo que citei o DBUNLOCK() é indiferente, ou não!?
Vejamos:
Código: Selecionar todos
SELECT DESDO
DBSETORDER(1)
GOTO TOP
DBSEEK(vPEDIDO)
DO WHILE CODPED = vPEDIDO
TRAVA()
DBDELETE()
DBUNLOCK()
DBSKIP()
ENDDO
DBCOMMITALL()
Digamos que no arquivo DESDO hajam
04 registros que satisfaz a pesquisa. Ele bloqueia o
1º e
deleta-o. Pra bloquear o
2º, antes ele tem que
DESBLOQUER o
1º. Pra BLOQUEAR o 3º, ele tem que DESBLOQUER a 2º e assim por diante...
Assim ele acabou DESBLOQUEANDO um registro ANTES do DBCOMMITALL().
Então o DBUNLOCK() depois do DBDELETE() (exemplo acima) é
INDIFERENTE nesse caso.
Falei alguma besteira??
Jânio
Enviado: 14 Set 2007 20:07
por Maligno
Por que ele está deletado. Mas veja: se você configurou para o sistema ignorar os registros deletados, após o SKIP você terá o ponteiro onde? Eu não tenho certeza de que ele estará apontando para o próximo registro vinculado ao pedido. Então, seria melhor você dar o SEEK dentro da malha. Se falhar, sai. Caso contrário, deleta.
Eu não faço assim. Meu método é diferente e não poderia fazer igual você. Eu limpo o registro inteiro pra só depois apagar. Mas meu esquema é automático. Eu tenho uma função que primeiro bloqueia todos os registros envolvidos e me devolve uma matriz com os números dos registros. Mando essa matriz pra outra função que faz o trabalho sujo. Ela limpa tudo, apaga e desbloqueia. Um por um. Mas só SE todos os registros foram bloqueados. Se falhar um que seja, pára tudo. Mas sem perder nada.
Na sua lógica o que aconteceria se TRAVA() falhasse por algum motivo, mas depois de ter apagado algum registro do conjunto? Era caca na certa. Tudo bem que pode ser até difícil de acontecer, mas eu não dou chance pro azar.

Enviado: 14 Set 2007 22:26
por alaminojunior
Mas no exemplo que citei o DBUNLOCK() é indiferente, ou não!?
Vejamos:
Código:
SELECT DESDO
DBSETORDER(1)
GOTO TOP
DBSEEK(vPEDIDO)
DO WHILE CODPED = vPEDIDO
TRAVA()
DBDELETE()
DBUNLOCK()
DBSKIP()
ENDDO
DBCOMMITALL()
Dbunlock() e DbCommit() tem finalidades distintas.
Dbcommitall() descarrega todos os buffers
Pesquisando a Biblia do Clipper aqui, encontrei que um simples
GOTO RECNO() descarrega o buffer da area atual (se ele tiver sido modificado)
Finalizando, faça como mencionou nosso querido Sygecom, com a sequencia:
Travar -> Editar ou Deletar -> Descarregar o buffer -> Destravar
Caso o laço seja muito grande (alterações ou deleções), deixe para descarregar ao final da operação. O que está armazenado em buffer é somente o registro atual, por isso um simples GOTO RECNO() resolveria.
Enviado: 15 Set 2007 01:26
por Maligno
Travar -> Editar ou Deletar -> Descarregar o buffer -> Destravar
Isso é o que sempre se aconselha.
O que está armazenado em buffer é somente o registro atual, por isso um simples GOTO RECNO() resolveria.
Mas é sempre bom lembrar a ressalva: numa malha, onde vários registros são alterados, o ideal é deixar o HD parado e fazer o COMMIT apenas após a saída da malha. Caso contrário, a performance cairá. Tanto quanto maior for a quantidade de registros alterados.