DICA: Uso de semaforo em sistemas com Fivewin.

Discussão sobre a biblioteca Fivewin - O Clipper para Windows.

Moderador: Moderadores

Avatar do usuário
rochinha
Administrador
Administrador
Mensagens: 4664
Registrado em: 18 Ago 2003 20:43
Localização: São Paulo - Brasil
Contato:

DICA: Uso de semaforo em sistemas com Fivewin.

Mensagem por rochinha »

Amiguinhos,

Ao implementar o procedimento de semaforos em nossos sistemas nos deparamos sempre com o seguinte problema:

Se um registro for travado em uma estação, outra estação não poderá ter acesso a alteração do mesmo. Então implementamos a seguinte mensagem. registro travado em outra estação.

Poxa, mas se ta travado não posso fazer nada?

Posso sim, Visualiza-lo.

Mas como visualizar sem causar algum tipo de problema no mesmo.

Como sabemos a função RLock() ou dbRlock() é uma faca de dois legumes. Se numa rede duas maquinas tentam ao mesmo tempo travar um registro no final o que teremos é um registro destravado, pois num milésimo de segundo o registro foi travado e no outro destravado.

Então a solução, sempre será o uso de semáforos e cada um implementa da forma mais coerente e funcional.

Estes problemas de travamento não é só dos RDDs NTX/CDX e acontecem também no MySQL( já tive relatos de dificuldades neste sentido ).

No meu caso, a idéia não seria apresentar uma mensagem ao usuário e fechar, mas sim permitir ao usuário ainda visualizar o registro sem permitir alterações.

Todas as minhas tabelas possuem um campo identificador unico que chamo de IDESTACAO mas voce pode criar o seu a seu gosto.

Em Fivewin ou outra GUI esta técnica seria possivel seguinte o exemplo abaixo:

Código: Selecionar todos

SELE CLIENTES
...
lSemaforo := .f.
if CLIENTES->IDESTACAO = 0
   // SEMAFORO LIGADO
   CLIENTES->( dbRLock() )
   CLIENTES->IDESTACAO := user_id // Travo o registro, salvo o IDentificador do usuario e libero o registro
   CLIENTES->( dbUnlock() )
   CLIENTES->( dbCommit() )
else
   lSemaforo := .t.
   //Isto eu nao quero
   //MsgRun( "Registro "+alltrim(str(CLIENTES->IDCLIENTE))+" sendo atualizacao em outra estacao!" )
   //return .t.
endif
...
// Carregos os campos em variaveis e faço a alteração ou visualizao
O pulo do gato ficaria por conta da propria interface:

Código: Selecionar todos

...
   ACTIVATE DIALOG oDialog ON INIT iif( lSemaforo, oButton:Disable(), oButton:Enable() )
...
Então o codigo de fechamento ficaria assim:

Código: Selecionar todos

...
REDEFINE BUTTON oButton ID  100 OF oDialog PROMPT "Confirma e fecha." ACTION ( lSave := .t. , oDialog:End() )
...
   ACTIVATE DIALOG oDialog ON INIT iif( lSemaforo, oButton:Disable(), oButton:Enable() )
   if lSave
      // Salvar o Registro
      ...
   else 
      GO nRegClient
      if CLIENTES->IDESTACAO # 0 // Se o registro foi marcado
         if CLIENTES->IDESTACAO = user_id // Se o usuario e o mesmo que marcou
            // MsgRun( "Liberando o registro" )
            // SEMAFORO LIGADO
            CLIENTES->( dbRLock() )
            CLIENTES->IDESTACAO := 0
            CLIENTES->( dbUnlock() )
            CLIENTES->( dbCommit() )
         endif
      endif
   endif
OPS! LINK QUEBRADO? Veja ESTE TOPICO antes e caso não encontre ENVIE seu email com link do tópico para [url=mailto://fivolution@hotmail.com]fivolution@hotmail.com[/url]. Agradecido.

@braços : ? )

A justiça divina tarda mas não falha, enquanto que a justiça dos homens falha porque tarda.
Avatar do usuário
rochinha
Administrador
Administrador
Mensagens: 4664
Registrado em: 18 Ago 2003 20:43
Localização: São Paulo - Brasil
Contato:

Re: DICA: Uso de semaforo em sistemas com Fivewin.

Mensagem por rochinha »

Amiguinho,

Costumo trabalhar em rede usando variáveis para suporte aos dados dos campos que pretendo alterar ou não.

No final se eu realmente desejo salvar o conteudo, executo o travamento do registro e pronto.

Este é o método praxe para manutenção de dados em rede.

O que não tem sentido seria usar um rlock() para travar um registro, tendo em vista que o mesmo é falho, ou nunca aconteceu com voce, de travar um registro em um terminal e outro terminal ao travar o mesmo registro destravar o primeiro.

Não usei aqui técnicas de semáforo para registro através de travamentos por rlock() e sim uma alternativa menos falível que a primeira.

Com certeza voce não entendeu a proposta da rotina e não leu os comentários.

O programador que se utilizar da rotina encontrará meios de melhorá-la ou pelo menos terá uma idéia de como usar a própria interface para auxiliá-lo.

A técnica do semáforo tem mais longevidade que meus poucos 25 anos de programação e raras vezes fiz uso da mesma.

Quanto a queda de energia, ai já é outra rotina...

Fique a vontade a melhorar a idéia.
OPS! LINK QUEBRADO? Veja ESTE TOPICO antes e caso não encontre ENVIE seu email com link do tópico para [url=mailto://fivolution@hotmail.com]fivolution@hotmail.com[/url]. Agradecido.

@braços : ? )

A justiça divina tarda mas não falha, enquanto que a justiça dos homens falha porque tarda.
Avatar do usuário
Pablo César
Usuário Nível 7
Usuário Nível 7
Mensagens: 5312
Registrado em: 31 Mai 2006 10:22
Localização: Curitiba - Paraná

DICA: Uso de semaforo em sistemas com Fivewin.

Mensagem por Pablo César »

O que não tem sentido seria usar um rlock() para travar um registro, tendo em vista que o mesmo é falho, ou nunca aconteceu com voce, de travar um registro em um terminal e outro terminal ao travar o mesmo registro destravar o primeiro.
Comigo nunca aconteceu isso ou ao menos nunca poderia ter acontecido, pois a idéia de travar registro pelo RLOCK() é necessária em rede mas o tratamento através de uso de semáforos aliada com todo o tratamento de rede (RLOCK, FLOCK, UNLOCK...) são bem vindos. Acho mais provável falhar o semáforos que não sejam bem implementados do que o uso do RLOCK. Bem essa é a minha opinião.
Um clip-abraço !

Pablo César Arrascaeta
Compartilhe suas dúvidas e soluções com todos os colegas aqui do fórum.
Evite enviar as dúvidas técnicas por MPs ou eMails, assim todos iremos beneficiar-nos.
Avatar do usuário
rochinha
Administrador
Administrador
Mensagens: 4664
Registrado em: 18 Ago 2003 20:43
Localização: São Paulo - Brasil
Contato:

Re: DICA: Uso de semaforo em sistemas com Fivewin.

Mensagem por rochinha »

Amiguinhos,

Me espressei mal ao comentar que o uso de RLock() é desnecessário.

Que fique bem frisado que RLock() é imprescindivel para o travamento de registros em rede.

Quanto a semáforos: estes são implementações para suprir a deficiencia dos travamentos.

E em relação a elas como disse anteriromente, raramente fiz uso.
OPS! LINK QUEBRADO? Veja ESTE TOPICO antes e caso não encontre ENVIE seu email com link do tópico para [url=mailto://fivolution@hotmail.com]fivolution@hotmail.com[/url]. Agradecido.

@braços : ? )

A justiça divina tarda mas não falha, enquanto que a justiça dos homens falha porque tarda.
Avatar do usuário
rochinha
Administrador
Administrador
Mensagens: 4664
Registrado em: 18 Ago 2003 20:43
Localização: São Paulo - Brasil
Contato:

Re: DICA: Uso de semaforo em sistemas com Fivewin.

Mensagem por rochinha »

Amiguinho,

Com toda franqueza, o intuito do tópico foi apresentar uma idéia, para quem quizer usar.

Se alguém optar por usá-la irá implementar para sua utilidade, caso não, simplemente passará batido.

Acho que em todo este tempo de forum, tentei me apresentar da forma mais simplória, apresentando soluções e dicas e nunca, nunca para discutir meu ponto de vista, caso eu ache que ele é melhor ou não.

Se não servir ao intuito, então exponha uma solução, e se possivel grátis, perca seu tempo aqui, ajudando, dando soluções ou passando o seu conhecimento, pois eu não disponho de muito tempo, mas quando posso tento ajudar de forma rápida.

Se um dia sentarmos para discutir programação, que seja numa mesa de bar, bebendo e gargalhando.

Seja breve e consiso e acima de tudo, me respeite.

Abaixo a transcrição de um email longinquo de um AmmIgo. Rápido e simples, apresentou uma solução apenas criticando os ponto fracos.
Rochinha,

En Clipper on line usted explica como usar semaforos.
Yo hace tiempo lo resolvi de otra forma y se lo comento por si le interesa.

Dado un documento o un cliente con el nº 000001, yo creo un archivo .txt que se llame:

Blq_Cliente_000001.txt y lo abro en modo shared.

Blq_cliente_000001.txt contiene la informacion del usuario que tiene el documento.


Lo que me di cuenta es que habia que sacar del tema de semaforos la logica de bloqueos rlock(), (nunca probe el multibloqueo) porque el mismo usuario que hace un rlock, puede querer hacer un unlock en otra derivacion del mismo programa:
Ademas con este sistema no es necesario ningun campo de id de la .dbf, ni tampoco identificar las estaciones de trabajo)

Voceto: Hay que añadir un array statico con los cid y los nHandle para cerrar:

FUNCTION Semaforo(cFile, cId, lSemaforo)
Local cFile:= cPath+ "Blq_"+ cFile+ "_"+ cId

IF lSemaforo
IF !File(cFile) .OR. lUsado(cFile)
ELSE
ENDIF
ELSE
DELETE FILE (cFile)
ENDIF
RETURN NIL


Saludos
OPS! LINK QUEBRADO? Veja ESTE TOPICO antes e caso não encontre ENVIE seu email com link do tópico para [url=mailto://fivolution@hotmail.com]fivolution@hotmail.com[/url]. Agradecido.

@braços : ? )

A justiça divina tarda mas não falha, enquanto que a justiça dos homens falha porque tarda.
Avatar do usuário
rochinha
Administrador
Administrador
Mensagens: 4664
Registrado em: 18 Ago 2003 20:43
Localização: São Paulo - Brasil
Contato:

Re: DICA: Uso de semaforo em sistemas com Fivewin.

Mensagem por rochinha »

Atenção,

Para que o tópico siga o rumo inicial sugiro que sejam postadas apenas soluções e implementações. Caso não irei tranca-lo.

Obrigado.
OPS! LINK QUEBRADO? Veja ESTE TOPICO antes e caso não encontre ENVIE seu email com link do tópico para [url=mailto://fivolution@hotmail.com]fivolution@hotmail.com[/url]. Agradecido.

@braços : ? )

A justiça divina tarda mas não falha, enquanto que a justiça dos homens falha porque tarda.
Trancado