Página 1 de 1

Como forçar o fechamento de DBFs na rede?

Enviado: 20 Ago 2007 11:24
por miracle
Existe jeito de forçar o fechamento de um arquivo DBF que está sendo usado por outro usuário da rede?

Enviado: 20 Ago 2007 11:53
por Maligno
Não. Mas o que você pode fazer é criar um sistema de identificação e notificação para pedir que esses usuários encerrem suas atividades.

Enviado: 20 Ago 2007 12:01
por janio
Estou com um problema semelhante.

Em algumas ocasiões uma estação não consegue gravar em um determinado dbf pq outro usuário está com o mesmo dbf (registro) aberto e travado com RLOCK(). E o usuário, impaciente como sempre, lasca um CTRL+ALT+DEL enquanto o sistema está aguardando o desbloqueio na outra estação.

Como resolver isso? ainda não sei...

Jânio

Enviado: 20 Ago 2007 12:08
por sygecom
Se vc usa o Windows XP ou 2003 como servidor e não esta abrindo esses DBF como Exclusivo, tem como fazer pelo Gerenciador de Computador que lista todos os DBF e EXE aberto....eu suo isso para aqueles usuario teimoso da REDE....claro que ah um risco nisso !!!....se o DBF estiver aberto como EXCL vai dar erro e não vai fechar !!! mas estou usando esse recurso do Windows ...e não deu problema ainda !!!....

Obs:Aconselho dar uma procurada na net por algo mais profissional...isso que faço não passa de uma Gambiara !!!


Abraços
Leonardo Machado

Enviado: 20 Ago 2007 12:08
por Maligno
Como resolver isso? ainda não sei...
No caso que você citou a única solução é orientar o usuário a não fazer isso, ao mesmo tempo em que o informa, pelo programa, que determinado arquivo ou registro está bloqueado por algum usuário em uma outra estação. Claro que você deverá usar um tempo de espera pequeno para que a máquina não fique travada enquanto o usuário aguarda o destravamento. Passado esse tempo, dê a opção para o apressadinho aguardar mais um tempo ou desistir.

Enviado: 21 Ago 2007 09:26
por janio
Maligno escreveu:Claro que você deverá usar um tempo de espera pequeno para que a máquina não fique travada enquanto o usuário aguarda o destravamento. Passado esse tempo, dê a opção para o apressadinho aguardar mais um tempo ou desistir.
Vejo um problema aí.

Quando preciso realizar gravações em vários DBF's, se tento travar para gravação um DBF lá no meio de uma rotina e não conseguir por ele estar sendo usado em outra estação, se eu abandonar essa rotina, pergunto: E o restante dos dados que devem ser gravados em VÁRIOS dbf's?

Exemplo: Na rotina abaixo preciso realizar gravação em 03 arquivos. O PRIMEIRO e no SEGUNDO dbf's consigo com hesito o travamento e gravação. Já no TERCEIRO não consigo o travamento e após esperar... esperar... esperar... dou ao usuário a opção de desistir e sair da rotina. E os dados já gravados no PRIMEIRO e no SEGUNDO???

Código: Selecionar todos

SELECT CAIXA
DBSETORDER(1)
GOTO TOP
DBSEEK(vNUMCXA)
TRAVA()
rSLDCXA = SLDCXA + vVLRDIN + vVLRCHQ
rSLDDIN = SLDDIN + vVLRDIN
rSLDCHQ = SLDCHQ + vVLRCHQ
replace SLDCXA with rSLDCXA ,;
            SLDDIN with rSLDDIN ,;
            SLDCHQ with rSLDCHQ
DESTRAVA()

SELECT CLIENTE
DBSETORDER(1)
GOTO TOP
DBSEEK(vCODCLI)
TRAVA()
vSALCLI = SALCLI + xVLRBAI
replace SALCLI with vSALCLI
DESTRAVA()

SELECT MOVCXA
TRAVA()
replace NUMMOV with vNUMMOV ,;
           NUMCXA with vNUMCXA ,;
           CODUSU with CODNOM  ,;
           DATMOV with vDATMOV ,;
           TIPMOV with "C"     ,;  // C - credito /  D - Debito
           CODHIS with vCODHIS ,;
           HISTOR with vHISTOR ,;
           TIPDOC with vTIPDOC ,;
           CODEMT with vCODEMT ,;
           NUMDOC with vNUMDOC ,;
           SEQDOC with vSEQDOC ,;
           SEQBAI with vSEQBAI ,;
           VLRMOV with vVLRMOV ,;
           VLRDIN with vVLRDIN ,;
           VLRCHQ with vVLRCHQ ,;
           FLGMOV with "1" 

         DBCOMMITALL()
         UNLOCK ALL
Jânio

Enviado: 21 Ago 2007 09:43
por Ademir
Bom dia Janio. Eu faço assim:

Só começo a gravar os registros depois de conseguir bloquear os 3 arquivos.

A medida que termino a gravação em cada um, vou desbloqueando.

Enviado: 21 Ago 2007 10:34
por Maligno
O Ademir deu a solução. E aí se nota como o código pode ficar macarrônico de tantos testes de abertura. E se fossem 10 arquivos?
Há algum tempo eu comentei sobre a necessidade de se criar um sub-sistema de controle de arquivos, semelhante ao que existe para GETs. Eu fiz o meu há alguns anos e nunca tive qualquer problema. Um exemplo:

Código: Selecionar todos

dbDefGroup Tempor kill create vital
dbDefGroup Client      create vital exclusive
dbDefGroup BasPAC      create vital
dbDefGroup ComPAC             vital
dbDefGroup MatPri      
dbDefGroup EstqEx      create vital
dbDefGroup ProAca2     create vital           tag "iPAC_PED"
dbDefGroup ProAca1            vital
dbDefGroup PedVnd2     create vital exclusive
dbDefGroup PedVnd1     create vital exclusive tag "iPVD_CLI"
dbDefGroup ProPed3     create vital
dbDefGroup ProPed2     create vital
dbDefGroup ProPed1     create vital exclusive tag "iPP1_SEQ"
*
if !dbOpenGrp()
   errDialog text "Arquivos não abertos"
   // ....
end
dbCloseGrp()
Nesse sistema simplificado, a função de abertura só retornará TRUE se todos os arquivos puderem ser abertos, a exceção daqueles que não têm a cláusula "VITAL". Serão bloqueados os que tiverem a cláusula "EXCLUSIVE". O arquivo temporário, no fechamento, será apagado.
Dá pra imaginar que, sem um sistema desses, a quantidade de IFs seria tremendamente grande.

Janio, sempre que for trabalhar com algo assim, mesmo não sendo algo relacionado a arquivos, você sempre deve pensar que alguma coisa do que foi feito vai dar errado. A partir daí, tente imaginar as piores situações possíveis. Só assim você vai conseguir minimizar a ocorrência desse e de outros tipos de erros.

Enviado: 21 Ago 2007 12:43
por Eolo
Uma coisa que dá pra fazer é derrubar o TBrowse() após algum tempo sem nenhuma ação do usuário. Por ex., o Fulano sai pra almoçar e larga o Vendas.DBF aberto na tela... No n-ésimo loop, o Tbrowse() é encerrado e o DBF pode ser UNLOCKado.

Código: Selecionar todos

ciclos=10 // limite pra ficar aberto sem nenhuma ação
do whil .t.
  (&nome):refreshall()
  (&nome):forceStable()
  lk:=inkey(5) // pausa de 5 segundos
  if lk=0
    ciclos--
    if ciclos=0
      * TBrowse() é derrubado
      exit
    endi
  elseif lk=27
    exit
  else
    * outras teclas...
    * teclou qq coisa, reinicia a contagem
    ciclos=10
  endi
endd

Enviado: 21 Ago 2007 23:51
por Stanis Luksys
janio escreveu:E o usuário, impaciente como sempre, lasca um CTRL+ALT+DEL
E você com isso? No meu sistema num faço nenhum tratamento estrambólico, não abriu da a mesagem e pergunta se quer continuar aguardando...

Se o usuário é espírito de porco, ele que tenha os dados corrompidos, Nem esquento a cabeça. Caiu no auditor que o sistema foi fechado incorretamente, o usuário fica sem argumento algum para cobrar algo.

Nenhum sistema é a prova de balas, é no máximo a prova de falhas. Se ele da um ctrl+alt+del para desligar o programa, também deve desligar o computador enquanto faz uma desfragmentação de disco que ta demorando. Enfim: falta orientação, ou inteligência.

Enviado: 21 Ago 2007 23:59
por Stanis Luksys
Outra coisa que me ocorre agora é o seguinte:

Eu por muito tempo fui avesso a criação de arquivos temporários, no entanto hoje quase todo o meu sistema, em especial as rotinas de movimentação, roda em cima deles, tudo local. Só vai pro servidor ao finalizar a tarefa, aí da um replace rápido em várias tabelas ao mesmo tempo. Existe um .prg a parte só para este super replace.

Há inclusive a possibilidade de se processar os arquivos ao entrar o sistema, pois ele avisa que o programa foi abortado no meio de um processo. Mesmo tendo uma parte sido gravada e outra não, consigo reprocessar (se o usário autorizar), ou então deletar o que já foi (se ele não autorizar).

Estive um tempo atrás desenvolvendo um novo módulo em que vou gravando a pilha de funções executadas, para que ao acontecer coisa deste tipo, ele já abrisse o sistema na tela que havia parado já com os dados do dbf temporário expostos na tela. Ainda não consegui implementar, mas desejo ainda dar continuidade nisso.