Página 1 de 2

Rotina com bloqueio de arquivo

Enviado: 19 Jul 2012 21:00
por Vandi
Boa noite,

Por gentileza, já fiz alguns testes utilizando flock() para bloqueio de arquivo, mas não obtive o êxito esperado, por isso recorro a ajuda aqui do grupo.
Preciso de uma rotina exemplo de acesso a arquivo que satisfaça as seguintes condições:
1)-Se o mesmo não estiver bloqueado, bloqueia-o e segue a rotina, com o desbloqueio no final da rotina;
2)-Se o mesmo estiver bloqueado, emite uma mensagem e volta ao início.

Aguardo retorno,

Agradecimentos antecipados,

Gilvandi

Rotina com bloqueio de arquivo

Enviado: 19 Jul 2012 21:26
por Imatech
Assunto já discutido no tópico:

https://pctoledo.org/forum/viewto ... ock#p76113



Aproveito para sugerir o estudo da pasta contrib\xhb que contem bons exemplos para uso imediato...
\harbour\contrib\xhb\ttable.prg

Código: Selecionar todos


NetDbUse( cDataBase, cAlias, nSeconds, cDriver, lNew, lOpenMode, lReadOnly )
NetLock( nType, lReleaseLocks, nSeconds )
NetFunc( bBlock, nSeconds )
NetOpenFiles( aFiles )
NetDelete()
NetReCall()
NetRecLock( nSeconds )
NetFileLock( nSeconds )
NetAppend( nSeconds, lReleaseLocks )
NetCommitAll()
IsLocked( nRecId )
NetError()
SetNetDelay( nSecs )
SetNetMsgColor( cColor )
TableNew( cDBF, cALIAS, cOrderBag, cDRIVER, lNET, cPATH, lNEW, lREADONLY )
GetTable( cAlias )
etc...


Rotina com bloqueio de arquivo

Enviado: 20 Jul 2012 00:38
por alxsts
Olá!

Pelos detalhes fornecidos, é mais prático abrir o arquivo de modo exclusivo.

Código: Selecionar todos

USE <xcFile> EXCLUSIVE NEW
. Ao final do processamento fechar o arquivo.

Rotina com bloqueio de arquivo

Enviado: 20 Jul 2012 12:04
por Vandi
Alexandre,
Bom dia...

Ok, mas eu te pergunto: digamos que eu abra o arquivo em modo exclusive, se outra estação for abrir o mesmo arquivo não dará um erro?

Gilvandi

Rotina com bloqueio de arquivo

Enviado: 20 Jul 2012 14:26
por alxsts
Olá!

Sim, a outra estação não conseguirá acessar o arquivo até que você o feche. O mesmo acontece com o arquivo se você colocar um FLock() nele.

Nos dois casos, o intuito é exatamente evitar que outros usuários acessem o arquivo. Não é isso que você precisa?

Rotina com bloqueio de arquivo

Enviado: 20 Jul 2012 14:49
por Vandi
Alexandre,
Boa tarde...

Sim, é isso mesmo que preciso, porém queria que, na tentativa de acesso ao arquivo por outra estação o sistema emita um aviso dizendo que o mesmo está inacessível e saísse da rotina, entendeu?
Como você aconselhou, já coloquei a abertura do arquivo em modo EXCLUSIVE, fiz alguns testes e funcionou OK. Mas não quero que a outra estação saia do programa em virtude de um erro por não conseguir acessar o arquivo, gostaria que o sistema fizesse uma crítica apenas.

Gilvandi

Rotina com bloqueio de arquivo

Enviado: 20 Jul 2012 15:23
por Toledo
Gilvandi, o Ronaldo passou várias funções para estudo, uma delas acho que iria fazer o que você precisa (NetDbUse), mas vou passar um função que muita gente aqui no fórum deve utilizar:

Código: Selecionar todos

FUNCTION Abre_Dbf(xcArquivo,xcAlias,lModo,nTentativa)
LOCAL lSempre
lSempre := (nTentativa == 0)
IF EMPTY(SELECT(xcAlias))
 DO WHILE (lSempre .OR. nTentativa > 0) .AND. INKEY() <> 27
   IF lModo                     && .T. ABRE ARQUIVO EXCLUSIVO ...
      USE (xBase+xcArquivo) ALIAS (xcAlias) EXCLUSIVE NEW
   ELSE                         && .F. ABRE ARQUIVO COMPARTILHADO ...
      USE (xBase+xcArquivo) ALIAS (xcAlias) SHARED NEW
   END
   IF (.NOT. NETERR())          && COM SUCESSO ...
      RETURN (.T.)
   END
   INKEY(1) 	          	&& TENTATIVAS 1 SEGUNDO ...
   nTentativa := nTentativa - 1
 END
ELSE
 SELE SELECT(xcAlias)
 RETURN (.T.)
ENDIF
RETURN (.F.)
Modo de usar:

Código: Selecionar todos

IF !Abre_Dbf("Arquivo","Alias",.T.,10)
  MsgInfo("Não foi possível abrir o Arquivo")
  RETURN
ENDIF
Abraços,

Rotina com bloqueio de arquivo

Enviado: 20 Jul 2012 16:26
por Vandi
Toledo,
Boa tarde...

Obrigado pela atenção... vou pegar essa rotina que vc dispôs aí e fazer uns testes mais tarde...

Gilvandi

Rotina com bloqueio de arquivo

Enviado: 07 Nov 2012 13:18
por Poka
Olá a todos

Toledo, sempre usei uma rotina parecida com essa sua.
Esses dias fazendo um teste + detalhado, percebi o seguinte:

Se tentar abrir um arquivo como exclusivo e o esse mesmo arquivo já foi aberto em outro terminal como exclusivo, o sistema da erro na abertura e trava o sistema antes do neterr

pergunto: para que serve o neterr?

Código: Selecionar todos

func abre_dbf(xNomearq,xModo,xAlias)
   // verifica se houve erro na abertura do arquivo
   local val:=.t.
   if ! xmodo   // tenta abrir conmpartilhado
      IF empty(select(xAlias))
         use (xnomearq) alias (xalias) shared new
      endif
   else 
			   // exclusivo
      IF empty(select(xAlias))
         use (xnomearq) alias (xalias) exclusive new
      endif
   endif
   if neterr()
      val=.f.  // nao abriu
   endif

retu (val)
[code]
Poka

Rotina com bloqueio de arquivo

Enviado: 07 Nov 2012 15:19
por Pablo César
pergunto: para que serve o neterr?
Ele serve para retornar o erro justamente de compartilhamento do arquivo. Ai o programa não será abortado no caso que você trate esse erro.

Rotina com bloqueio de arquivo

Enviado: 09 Nov 2012 08:29
por Poka
Pablo,

obrigado por responder.

Eu já uso o neterr, acontece que o erro dá na linha
USE (XNOMEARQ)
não chega até a linha do neterr.
Sempre achei que o neterr "trabalhasse" igual as funcões FOPEN() e FERROR(), onde
o erro não trava no fopen() e voce testa na função ferror(), a não ser que na minha rotina esteja faltando algo.

Poka

Rotina com bloqueio de arquivo

Enviado: 09 Nov 2012 12:11
por Pablo César
Eu não sei como você está usando ao ponto de dizer que não esteja funcionando. Olha eu fiz estes testes de exemplos baseado um no código do Toledo e o outro do Maligno. Aqui está funcionando perfeitamente.
Sempre achei que o neterr "trabalhasse" igual as funcões FOPEN() e FERROR()
Não funcionam exatamente iguais*, mas dá para obter o mesmo resultado.

Faça os testes indicados nesse tópico com os executáveis em anexo, para comparar casa a caso (aconselho que sejam feito na linha de comando).

*Digo não iguais, porque o FOpen tem mais opções que o USE. O FOpen pode abrir os arquivos em modo:
&nbspModo&nbsp&nbspValor&nbsp
&nbspREAD&nbsp&nbsp0&nbsp
&nbspWRITE&nbsp&nbsp1&nbsp
&nbspREADWRITE&nbsp&nbsp2&nbsp
&nbspEXCLUSIVE&nbsp&nbsp16&nbsp
&nbspDENYWRITE&nbsp&nbsp32&nbsp
&nbspDENYREAD&nbsp&nbsp48&nbsp
&nbspDENYNONE&nbsp&nbsp64&nbsp
Apesar de que o USE pode abrir também em READONLY, isto é impedido quando é aberto em modo EXCLUSIVE. Já isto pode ou não acontecer com FOpen(), tudo depende com qual modo você irá abrir o arquivo (ver tabela acima). Faça outro comparativo abrindo em ReadOnly com estes exemplos aqui em anexo.

Rotina com bloqueio de arquivo

Enviado: 09 Nov 2012 19:25
por Poka
Pablo,

Mais uma vez obrigado pela sua paciência e dedicação.

1) testei a sua rotina

Resultado:

perfeito, era isso mesmo que eu imaginava que fizesse, mas no meu sistema dava erro. No meu sistema trabalho normal abrindo os arquivos, mas num caso de precisar abrir exclusivo dava erro. Por isso a minha pergunta "para que servia o neterr?".

2) No meu sistema desativei a minha rotina, coloquei a sua.

Resultado:

O erro continua
FALHA DBFCDX\1001 ERRO DE ABERTURA: ARQUIVO.DBF
na linha do USE NOMEARQ antes do neterr.

3) Criei novo projeto com as mesmas configurações iniciais que utilizo (achei que pudesse ser alguma configuração que estivesse causando o erro), utilizo Harbour + Minigui.

Resultado:

perfeito, sem nenhum erro.


Vou continuar "quebrando a cabeça" por aqui para ver se descubro qual o problema, (pelo menos agora sei que o neterr funciona como o esperado) "

Assim que solucionar o problema volto nesse tópico para postar o resultado.

Um abraço


Poka

Rotina com bloqueio de arquivo

Enviado: 10 Nov 2012 14:31
por Pablo César
Poka escreveu:num caso de precisar abrir exclusivo dava erro. Por isso a minha pergunta "para que servia o neterr?"
O NetErr() irá dar retorno de erro, quando este for tentar abrir em modo EXCLUSIVO, pois se tiver alguma estação aberto antes, seja em modo COMPARTILHADO ou EXCLUSIVO, irá dar erro igual.

A abertura em modo EXCLUSIVO tem que ser evitado o máximo possível em uma rede. Tudo tem que ser avaliado, buscar outra solução pode ser o caso.
O erro continua
FALHA DBFCDX\1001 ERRO DE ABERTURA: ARQUIVO.DBF
na linha do USE NOMEARQ antes do neterr.
Se nessa linha só contiver USE NOMEARQ sem mais nada. Então é o mesmo que abrir em modo EXCLUSIVO e se outra estação estiver com o arquivo aberto, evidentemente irá dar erro. Aconselho também abrir o DBF antes e depois os índices após ter passado pelo NetErr().

Rotina com bloqueio de arquivo

Enviado: 10 Nov 2012 17:59
por Poka
Pablo

Resolvido!!
PUBL OERRANTES, OERR
// LMYERROR = .T. - SI OCURRIO REALMENTE UN ERROR, .F. - PARA CONTROLAR LOS BREAK
PUBL LMYERROR := .F.
ERRORBLOCK({ |OBJERR| MYERRORFUNC(OBJERR) })
Esse texto estava na rotina inicial, que serve para todos os sistemas. Foi só desativar que funcionou corretamente.

Quando comecei a utilizar o x(harbour), devo ter copiado de alguma rotina exemplo, por isso o neterr não estva funcionando como devia.

Obrigado Pablo

Poka