No. do pedido repetido

Projeto [x]Harbour - Compilador de código aberto compatível com o Clipper.

Moderador: Moderadores

Stanis Luksys
Colaborador
Colaborador
Mensagens: 1329
Registrado em: 18 Jun 2005 03:04
Localização: São Paulo
Contato:

No. do pedido repetido

Mensagem por Stanis Luksys »

Sim,

A função tenta travar o arquivo inteiro, o que significa que mesmo que exista um usuário utilizando outro registro, ela não consegue travar. Quanto maior o tempo deste parâmetro, mais tempo ela fica em loop, e maior a chance de outro usuário pegar o mesmo número.

Neste caso do exemplo, não consegui entender a necessidade de travar o arquivo inteiro.

Eu acho que seria melhor algo do tipo:

Código: Selecionar todos

dbgobottom() 
DO WHILE .T.
  sPedido:=Pedido+1
  If ! DbSeek(sPedido)
        dbappend()
	     replace pedido     with SPEDIDO
	     dbunlock() 
   endif	 
enddo
Abraços
Stanis Luksys
sites.google.com/hblibs

Apoiar e se utilizar de projetos opensource não é uma questão de boicote, mas sim de liberdade.
Utilize, aprimore e distribua.
marcos.gurupi
Usuário Nível 4
Usuário Nível 4
Mensagens: 939
Registrado em: 06 Jul 2004 11:53
Localização: Gurupi-TO

No. do pedido repetido

Mensagem por marcos.gurupi »

Obrigado pela resposta.
Bom eu uso assim a muito, muito tempo; mas é claro que preciso estah aberto para novas possibildades.
Agora eu imagino/imaginava que é necessário o travamento do arquivo para uma inclusão, principalmente por que tem a necessidade de um dbappend(), quando eu estou alterando ou excluindo um registro ai sim eu uso travar somente o registro em questao. Estou errado ?
Marcos Roberto
NetService Software
Stanis Luksys
Colaborador
Colaborador
Mensagens: 1329
Registrado em: 18 Jun 2005 03:04
Localização: São Paulo
Contato:

No. do pedido repetido

Mensagem por Stanis Luksys »

marcos.gurupi escreveu:Agora eu imagino/imaginava que é necessário o travamento do arquivo para uma inclusão, principalmente por que tem a necessidade de um dbappend(), quando eu estou alterando ou excluindo um registro ai sim eu uso travar somente o registro em questao. Estou errado ?
Sim, não é necessário travar o arquivo para criar novo registro, o próprio DbAppend() se encarrega de travar o registro que será gravado. Um DbAppend() é a mesma coisa que isso:

Código: Selecionar todos

DbGoBottom()
DbSkip()
RLock()
Abraços.
Stanis Luksys
sites.google.com/hblibs

Apoiar e se utilizar de projetos opensource não é uma questão de boicote, mas sim de liberdade.
Utilize, aprimore e distribua.
MARCELOG
Usuário Nível 4
Usuário Nível 4
Mensagens: 546
Registrado em: 15 Mar 2005 16:54
Localização: Divinópolis/MG

No. do pedido repetido

Mensagem por MARCELOG »

Oi Marcos,
quando trabalhava com dbf e precisava de número único usava um arquivo texto em separado que também era integralmente bloqueado.
Era uma rotina disponibilizada no site caclipperwebsite.
Lá também tinha uma dica bem legal acerca de utilização do sistema em rede de computadores (registro fantasma, atualização perdida, etc.).
Já a proposta do Stanis funciona, todavia não é 100%, podendo ocorrer a duplicidade não desejada.
O dbf não tem recurso de campo "unique".
E é isso que você quer não é?
Ou seja, que o campo (coluna) pedido do arquivo pedido tenha números sequenciais sem repetição.
Então, sem o travamento do arquivo, dois ou mais usuários poderão gravar o mesmo sPedido definido num mesmo momento anterior.
Espero ter ajudado.

MarceloG
Água mole em pedra dura tanto bate que até espirra!
Stanis Luksys
Colaborador
Colaborador
Mensagens: 1329
Registrado em: 18 Jun 2005 03:04
Localização: São Paulo
Contato:

No. do pedido repetido

Mensagem por Stanis Luksys »

Veja bem,

Acho que está ocorrendo uma confusão. Travar o arquivo não serve de nada, pois o travamento de DBF via flock(), não impede que outro usuário "leia" o arquivo, não é a mesma coisa que abrir exclusivo, e portanto outro usuário pode pegar o mesmo número de qualquer jeito.

Claro que o ideal é se fazer um controle externo, como já foi sugerido, através de uma outra tabela que contenha as sequencias, ou mesmo por um txt, etc.

O exemplo que eu dei foi só no intuito de aprimorar o código que foi apresentado, que contem alguns erros de lógica que aumentam o tempo entre pegar o número e gravar no banco. Quanto maior este tempo, maior a chance de duplicidade.
Stanis Luksys
sites.google.com/hblibs

Apoiar e se utilizar de projetos opensource não é uma questão de boicote, mas sim de liberdade.
Utilize, aprimore e distribua.
MARCELOG
Usuário Nível 4
Usuário Nível 4
Mensagens: 546
Registrado em: 15 Mar 2005 16:54
Localização: Divinópolis/MG

No. do pedido repetido

Mensagem por MARCELOG »

Oi Marcos,
a situação de pesquisa, inserção e gravação de novo registro é rápida.
Por isso a proposta do Stanis funciona.
Mas como todas, inclusive a que tinha postado anteriormente não é 100% e/ou compromete o desempenho em rede com a necessidade de abertura do arquivo de dados no modo exclusivo.
O dbf não tem recurso de campo "unique".
E é isso que você quer não é?
Ou seja, que o campo (coluna) pedido do arquivo pedido tenha números sequenciais sem repetição.
Então, analisando mais detidamente o seu problema, acho que a melhor técnica é utilizar um arquivo texto em separado, que grava o número do pedido.
Quando utilizava dbf eu usava uma função que fazia isso, obtida no site caclipperwebsite.
Deu até saudade...
Fui lá e peguei ela prá você.
É muito simples o uso...

Código: Selecionar todos

FUNCTION NOVOCOD(ARQUIVO)
IF !FILE(ARQUIVO)
__nHandle := FCREATE(ARQUIVO, 0)
__IF FERROR() # 0
____ALERT("Erro"+ALLTRIM(STR( FERROR() ))+": Arquivo não pode ser criado!!!" )
____QUIT
__ELSE
____FWRITE(nHandle, "000000")
____FCLOSE(nHandle)
__ENDIF
ENDIF
nHandle := FOPEN(ARQUIVO, 18)
IF FERROR() != 0
__ALERT("Erro"+ALLTRIM(STR( FERROR() ))+": Arquivo não pode ser aberto!!" )
__QUIT
ENDIF
nCOD := VAL( FREADSTR(nHANDLE, 6) )
nCOD++
FSEEK(nHANDLE, 0)     
FWRITE(nHANDLE, STRZERO(nCOD,6))
FCLOSE(nHANDLE)
RETURN (nCOD)
Espero ter ajudado.

MarceloG

PS: tinha feito confusão mesmo.
Editado pela última vez por Toledo em 01 Nov 2013 18:43, em um total de 1 vez.
Razão: Mensagem editada para colocar a tag [ code ]<br>Veja como utilizar esta tag: http://www.pctoledo.com.br/forum/faq.php?mode=bbcode#f2r1
Água mole em pedra dura tanto bate que até espirra!
Responder