Página 1 de 1
Orientação
Enviado: 26 Set 2016 22:40
por fladimir
Olá pessoal td bem...
Seguinte tem uma situação q não consigo isolar q é o seguinte, alguns clientes, poucos na verdade reclamam q eventualmente algum produto e/ou cliente (some), ai analisando os registros não é localizado tipo foi excluído do DBF, mas se olharmos bkps o bendito esta lá...
Isso já faz algum tempo, já revisei as rotinas e se um produto é excluído via sistema é alimentada uma outra tabela q registra os itens excluídos e da mesma maneira com clientes... mas qdo "some" não consta nessa tabela e não consigo saber se é algum erro de lógica e/ou outro problema.
O cliente acha q é pq uso DBF e não SGBD (no caso do sistema dele, hj uso SGBD em sistemas/projetos mais recentes e/ou menores), mas não sei se o fato de ser DBF pode acarretar isso..
Alguém já passou por isso ou tem alguma dica pra me ajudar?
[]´s
Orientação
Enviado: 27 Set 2016 00:04
por JoséQuintas
Nunca vi isso.
Ele se encontra como deletado?
Tem algum esquema de reaproveitamento de registros excluídos que poderia estar falhando?
Orientação
Enviado: 27 Set 2016 08:39
por rubens
Fladimir...
Já verificou a rotina de alteração? Na minha rotina de importação de xml tinha um erro que não voltava no registro inicial e gravava os dados do fornecedor em qualquer outro registro... daí o fornecedor sumia do nada...
Em outro caso não sei por que razão motivo circunstância apareceum um registro em branco... daí a bagunça tava feita tb...
Orientação
Enviado: 27 Set 2016 08:59
por JoséQuintas
Pera aí... mesmo aplicativo em vários clientes.
Só alguns reclamam.
Esses clientes usam alguma coisa que os outros não usam? que poderia desposicionar registro ou área?
Problema de rede danificando índice?
Orientação
Enviado: 27 Set 2016 09:56
por fladimir
Então pessoal...
Eu descartei problema de rede pq nesses casos em q uso DBF é via TS ou seja o processamento é todo no Servidor...
Queria bolar algo pra saber se esta sendo realmente deletado o registro e gravar um log ai acho q iria entender melhor... pq os clientes q reclamaram são segmentos diferentes.. .usam basicamente o mesmo cadastros (produto, clientes, etc), vendas (uns só a vista e outros a vista e a prazo) orçamentos, entrada de notas/pedidos (uns não importam XML somente lançam pedido, outros importam) e relatórios de análise (balanço, comissões, estoque etc)
O Objetivo desse tópico seria saber se alguém já passou por isso e o q poderia ser igual o Rubens mencionou q pelo q entendi era sobrescrito um registro anterior... não analisei isso, pra saber isso acho q é até fácil tipo como os códigos são sequenciais ai por exemplo se tem 1, 2, 3, 4 e o cliente reclamou q sumiu o produto XPTO e olhando os bkps vermos q era o codigo 2 e no lugar do 2 estiver um codigo mais alto tipo 1, 9, 3, 4 se for isso já entenderei uma hipótese... Vou verificar isto...
Orientação
Enviado: 27 Set 2016 10:20
por JoséQuintas
Uma situacão que poderia gerar isso, por exemplo num cadastro de clientes, com checagem de CNPJ repetido, e na checagem não retornar à posição correta antes do replace.
Não conseguiu identificar algo comum?
Qual o uso dos registros que sumiram? eram registros antigos, ou registros novos que usou uma única vez?
O que uso é uma rotina GravaOcorrencia() que insiro em tudo que é lugar que acho interessante.
Pode ser uma ocorrência geral, ou com identificação de arquivo/código pra ficar anexa a algum cadastro.
Ocorrências:
arquivo, C, 10
código, C, 9
texto, C, 100
informacão de inclusão (usuário, data, hora, terminal, módulo do aplicativo, etc), C, 80
Inclusive este foi o primeiro dos arquivos que comecei a gravar em MySQL, assim tamanho deixa de ser problema, e da pra expandir cada vez mais.
Orientação
Enviado: 27 Set 2016 10:59
por asimoes
Fladimir,
O seu sistema tem auditoria ?
Outra coisa é criar um campo chksum, para saber se os dados não foram alterados por fora.
Orientação
Enviado: 27 Set 2016 11:30
por JoséQuintas
Desde os tempos do Clipper uso SKIP 0 antes do UNLOCK.
É importante atualizar o registro antes de desbloquear.
Apesar de ser mesmo aplicativo em vários clientes, tem cliente que não inclui coisa nova todo dia e toda hora, ou até mesmo alguns definem um setor só para cadastramento.
A rotina operacional acaba sendo diferente.
No Clipper tinha um caractere esquisito que poderia entrar no DBF, e considerar um registro excluído mesmo não estando excluído.
1) Se foi deletado, deveria estar como deletado no DBF, se não está... reindexa tanto assim?
2) Só por garantia, recriar o DBF com COPY TO ou APPEND FROM
3) Registrar inclusões/exclusões
Seria possivel que o problema seja "não incluir"?
Lembro de uns tipos de vírus que não salvavam no HD, e tem o virus "usuário", que poderia fechar no "X" ou fechar o Windows antes do salvamento.
O registro seria válido enquanto o programa estivesse aberto, e só para aquele terminal, e se fechar o programa pelo "X" os outros terminais nem saberiam que ele existe.
Tem uns pontos de parada perigosos:
Dependendo de como colocar no programa pra aguardar o Windows, o Windows considera que o programa travou e fecha tudo.
Para o usuário, coisas que consideramos problema, eles acostumam a considerar normal.
Isso pode ser comum numa rotina de envio de email, por exemplo, e outras.
Nessas horas talvez seja até bom usar multithread.
Orientação
Enviado: 27 Set 2016 12:40
por fladimir
asimoes » 27 Set 2016, 10:59
Fladimir,
O seu sistema tem auditoria ?
Outra coisa é criar um campo chksum, para saber se os dados não foram alterados por fora.
Em q sentido Alexandre? Coloquei recentemetne uma rotina q cada menu acessado grava em uma tabela Auditoria... seria isso, tipo o q o usuário acessou?
Orientação
Enviado: 27 Set 2016 12:53
por fladimir
JoséQuintas » 27 Set 2016, 11:30
Desde os tempos do Clipper uso SKIP 0 antes do UNLOCK.
É importante atualizar o registro antes de desbloquear.
Então esses tempos (ou anos) vi em um tópico essa dica sua e alterei minha rotina por via das dúvidas... mas já faz um bom tempo q esta assim.
JoséQuintas » 27 Set 2016, 11:30
No Clipper tinha um caractere esquisito que poderia entrar no DBF, e considerar um registro excluído mesmo não estando excluído.
1) Se foi deletado, deveria estar como deletado no DBF, se não está... reindexa tanto assim?
2) Só por garantia, recriar o DBF com COPY TO ou APPEND FROM
3) Registrar inclusões/exclusões
Então não fica como Deletado no DBF... reindexa 1 x ao mês
Recriar o DBF por garantia vc se refere a questão de talvez algum problema no Header etc? Se sim sempre qdo atualizo é feito esse procedimento
Registrar Inclusões e Exclusões faço da seguinte forma... tem dodo PRG tenho 1 CH comum e neste CH esta assim um determinado trecho:
Código: Selecionar todos
#command PACK => __dbPack() ; dbCommitLog( 'P', PROCNAME(), PROCLINE(), cDBCommitLog )
#command ZAP => __dbZap() ; dbCommitLog( 'Z', PROCNAME(), PROCLINE(), cDBCommitLog )
#command DELETE => My_DBDelete()
#command DBDELETE() => My_DbDelete()
#command APPEND BLANK => dbAppend( 0 ) ; dbCommitLog( 'I', PROCNAME(), PROCLINE(), cDBCommitLog )
#command REGLOCK => dbRegLock( 0 ) ; dbCommitLog( 'B', PROCNAME(), PROCLINE(), cDBCommitLog )
#command RLOCK() => dbRegLock( 0 ) ; dbCommitLog( 'B', PROCNAME(), PROCLINE(), cDBCommitLog )
#command REGLOCK <n> => dbRegLock( <n> ) ; dbCommitLog( 'B', PROCNAME(), PROCLINE(), cDBCommitLog )
#command FILELOCK => dbFileLock( 0 ) ; dbCommitLog( 'F', PROCNAME(), PROCLINE(), cDBCommitLog )
#command FILELOCK <n> => dbFileLock( <n> ) ; dbCommitLog( 'F', PROCNAME(), PROCLINE(), cDBCommitLog )
procedure MY_DBDELETE()
* ROTINA PARA NA HORA DO DELETE SETAR O INDICE ZERO E MELHORAR A ESTABILIDADE DOS DBFCDX
LOCAL nIdx := OrdNumber()
while ! dbRLock() // antes era somente dbRLock() dica do Quintas seria interessante dar uma pausa
inkey(0.5)
end
dbSetOrder(0)
dbDelete()
dbCommit()
dbSetOrder(nIdx)
dbSkip( 0 ) // dica Quintas topic 16174
dbUnLock()
dbCommitLog( 'E', PROCNAME(), PROCLINE(), cDBCommitLog )
return
JoséQuintas » 27 Set 2016, 11:30
Seria possivel que o problema seja "não incluir"?
Lembro de uns tipos de vírus que não salvavam no HD, e tem o virus "usuário", que poderia fechar no "X" ou fechar o Windows antes do salvamento.
O registro seria válido enquanto o programa estivesse aberto, e só para aquele terminal, e se fechar o programa pelo "X" os outros terminais nem saberiam que ele existe.
Então isso ocorre mesmo do usuário fechar no X a sessão do Terminal Services (no sistema retirei o X, mas do TS permanece) ou as vezes reiniciar o server por queda de energia e não tem nobreak ai derruba todo mundo... esse tipo de coisa eventualmente ocorre.
JoséQuintas » 27 Set 2016, 11:30
Tem uns pontos de parada perigosos:
Dependendo de como colocar no programa pra aguardar o Windows, o Windows considera que o programa travou e fecha tudo.
Para o usuário, coisas que consideramos problema, eles acostumam a considerar normal.
Isso pode ser comum numa rotina de envio de email, por exemplo, e outras.
Nessas horas talvez seja até bom usar multithread.
Então isso não sei muito bem, mas acredito estar relacionado a explicação anterior talvez.
Orientação
Enviado: 27 Set 2016 13:37
por JoséQuintas
Eu uso estas.
Não sei se você usa controle para o APPEND BLANK.
Código: Selecionar todos
#include "jpa.ch"
#include "inkey.ch"
FUNCTION RecLock( lForever )
LOCAL nCont := 1
hb_Default( @lForever, .T. )
wSave( MaxRow() - 1, 0, MaxRow(), MaxCol() )
DO WHILE .T.
IF rLock()
SKIP 0
EXIT
ENDIF
Mensagem( "Aguardando liberação do registro em " + Alias() + "... Tentativa " + lTrim( Str( nCont ) ) + iif( lForever, "", ". ESC cancela" ) )
IF Inkey( 0.5 ) == K_ESC .AND. ! lForever
EXIT
ENDIF
nCont += 1
ENDDO
WRestore()
RETURN ( rLock() )
FUNCTION RecAppend( lForever )
LOCAL nCont := 1, lOk := .F.
hb_Default( @lForever, .T. )
wSave( MaxRow()-1, 0, MaxRow(), MaxCol() )
DO WHILE .T.
APPEND BLANK
IF ! NetErr()
lOk := .T.
RecLock()
SKIP 0
EXIT
ENDIF
Mensagem( "Aguardando liberação do arquivo: " + Alias() + "... Tentativa " + LTrim( Str( nCont ) ) + iif( lForever, "", ". ESC cancela" ) )
IF Inkey( 0.5 ) == K_ESC .AND. ! lForever
EXIT
ENDIF
nCont += 1
ENDDO
WRestore()
RETURN lOk
FUNCTION RecDelete( lForever )
LOCAL lOk := .F.
hb_Default( @lForever, .T. )
IF RecLock( lForever )
DELETE
RecUnlock()
lOk := .T.
ENDIF
RETURN lOk
FUNCTION RecUnlock()
SKIP 0
UNLOCK
RETURN NIL
Estranhei controlar o PACK e ZAP, à primeira vista seria muito pouco o uso.
PACK no Clipper dava problema, de duplicar registros ou sumir registros, mas não sempre.
Como as rotinas estavam prontas, nunca alterei isso no Harbour.
Na minha reindexação é COPY TO ou APPEND FROM, mas não PACK.
Mas ela é muito pouco usada.
Basicamente uso:
Código: Selecionar todos
RecLock()
REPLACE ...
RecUnlock()
// ou
RecAppend()
REPLACE ...
RecUnlock()
// ou
RecDelete()
Orientação
Enviado: 27 Set 2016 13:50
por JoséQuintas
Microsoft é phoda, não faz mais nada direito.
O mesmo post, que acabei de fazer, aqui W10 e Firefox

- postfirefox.png (6.96 KiB) Exibido 1289 vezes
Aqui W10 e Edge, com espacejamento duplo.

- postedge.png (8.6 KiB) Exibido 1289 vezes
Até num simples post ela consegue fazer diferente ... rs
Orientação
Enviado: 27 Set 2016 13:58
por asimoes
Fladimir,
Você usa terminal service, certo? você tem algum controle quando o usuário sai normalmente do sistema? e quando não sai? tipo fecha a seção pelo X da janela ou até por falta de energia mesmo.
Orientação
Enviado: 27 Set 2016 15:11
por Claudio Soto
fladimir escreveu:
Registrar Inclusões e Exclusões faço da seguinte forma... tem dodo PRG tenho 1 CH comum e neste CH esta assim um determinado trecho:
Código: Selecionar todos
#command PACK => __dbPack() ; dbCommitLog( 'P', PROCNAME(), PROCLINE(), cDBCommitLog )
#command ZAP => __dbZap() ; dbCommitLog( 'Z', PROCNAME(), PROCLINE(), cDBCommitLog )
#command DELETE => My_DBDelete()
#command DBDELETE() => My_DbDelete()
#command APPEND BLANK => dbAppend( 0 ) ; dbCommitLog( 'I', PROCNAME(), PROCLINE(), cDBCommitLog )
#command REGLOCK => dbRegLock( 0 ) ; dbCommitLog( 'B', PROCNAME(), PROCLINE(), cDBCommitLog )
#command RLOCK() => dbRegLock( 0 ) ; dbCommitLog( 'B', PROCNAME(), PROCLINE(), cDBCommitLog )
#command REGLOCK <n> => dbRegLock( <n> ) ; dbCommitLog( 'B', PROCNAME(), PROCLINE(), cDBCommitLog )
#command FILELOCK => dbFileLock( 0 ) ; dbCommitLog( 'F', PROCNAME(), PROCLINE(), cDBCommitLog )
#command FILELOCK <n> => dbFileLock( <n> ) ; dbCommitLog( 'F', PROCNAME(), PROCLINE(), cDBCommitLog )
procedure MY_DBDELETE()
* ROTINA PARA NA HORA DO DELETE SETAR O INDICE ZERO E MELHORAR A ESTABILIDADE DOS DBFCDX
LOCAL nIdx := OrdNumber()
while ! dbRLock() // antes era somente dbRLock() dica do Quintas seria interessante dar uma pausa
inkey(0.5)
end
dbSetOrder(0)
dbDelete()
dbCommit()
dbSetOrder(nIdx)
dbSkip( 0 ) // dica Quintas topic 16174
dbUnLock()
dbCommitLog( 'E', PROCNAME(), PROCLINE(), cDBCommitLog )
return
Solo a modo de comentario, una vez cree unas rutinas para los fuentes de HMG y las llamaba mediente una directiva #command xxx ...., pero por error le di a xxx el mismo nombre que un comando definido en harbour también con #command y dio problema. En algunos usuarios funcionaba ok mientras que en otros llamaba el comando original de harbour. Tuve que renombrar mi comando y se soluciono el problema.
Orientação
Enviado: 27 Set 2016 18:55
por fladimir
Zé... vou dar uma olhada nessa parte q vc comentou..
Alexandre... não tenho esse controle...
Claudio Soto » 27 Set 2016, 15:11
Solo a modo de comentario, una vez cree unas rutinas para los fuentes de HMG y las llamaba mediente una directiva #command xxx ...., pero por error le di a xxx el mismo nombre que un comando definido en harbour también con #command y dio problema. En algunos usuarios funcionaba ok mientras que en otros llamaba el comando original de harbour. Tuve que renombrar mi comando y se soluciono el problema.
Obrigado pela informação Dr. Claudio.