Clipper On Line • Ver Tópico - LetoDB - Problemas com DbCommit()
Página 1 de 2

LetoDB - Problemas com DbCommit()

MensagemEnviado: 16 Out 2010 23:02
por alaminojunior
Estou fazendo um trabalho aqui com LetoDB, e me deparei com o seguinte:
Numa rotina de numeração de pedidos.
   sele cdpar000
   do while .t.
      if !rlock()
         msgexclamation("Aguardando para criar novo orçamento ...","ATENÇÃO")
         loop
      else
         repl numnum with numnum + 1
         dbcommit()
         orc = numnum
         dbunlock()

Este trecho assegura que dois usuários não possam iniciar um pedido com o mesmo número, e com DBFCDX sempre funcionou.
Se eu tentar criar um pedido em dois pc´s diferentes ao mesmo tempo, ocorre a mensagem de que o arquivo está travado, porém quando um pc destrava o arquivo, o pedido no outro pc é criado com o mesmo número do anterior. É como se houvesse um dbf para cada pc.
Ví um post do Itamar explicando sobre o uso de variáveis neste contexto de cliente/servidor e acredito ser este o entrave, mas confesso não estar encontrando a saída.

Em tempo:
REQUEST LETO
RDDSETDEFAULT( "LETO" )

Para abrir o dbf eu uso:
use &arquivo shared new

Onde arquivo é: //192.168.0.10:2812/ + nome do arquivo sem extensão

Re: LetoDB - Problemas com DbCommit()

MensagemEnviado: 17 Out 2010 22:56
por asimoes
Alamino eu faço assim:

Abre('//192.168.0.1:2815/',"CADASTRO")   
SELECT Cadastro

IF CADASTRO->(DbRLock())
   CADASTRO->Codigo:=cCodigo
   CADASTRO->(DbCommit())
   CADASTRO->(DbUnlock())
ELSE
   msgexclamation("Aguardando liberação de registro ...","ATENÇÃO")
   LOOP
ENDIF


FUNCTION NetUse(cServer,cDatabase,lOpenMode,nSeconds,cRDD)
LOCAL lForever, cDirTab:=""

DEFAULT lOpenMode TO .F.,;
        nSeconds  TO 0,;
        cRDD      TO "DBFCDX",;
        cServer   TO ""

lForever := (nSeconds = 0)
Do While (lForever .Or. nSeconds > 0)
   If lOpenMode
      DBUseArea(.T.,,cServer+cDataBase,cDataBase,.F.,"DBFCDX")
   Else
      DBUseArea(.T.,,cServer+cDataBase,cDataBase,.T.,"DBFCDX")
   EndIf
   If ! NetErr()                    // Use succeeds
      RETURN (.T.)
   EndIf
   Inkey(1)         // Wait 1 second
   nSeconds --
EndDo
RETURN (.F.)


#include "common.ch"
FUNCTION Abre(cServer,cDataBase,lExclusive,cArqTemp,lNomeTabela)
LOCAL nArea, cDirSys:=cServer
DEFAULT lExclusive  TO .F.,;
        cArqTemp    TO "",;
        lNomeTabela TO .T.,;
        cServer     TO ""

// ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
//  Abre o Arquivo necessario na rotina.
// ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ

IF Alias() = Upper(cDataBase)
   DbSelectArea(cDataBase)
   RETURN .T.
ENDIF
FOR nArea:=0 To 100
   IF !Empty((nArea)->(Alias()))
      If RTrim((nArea)->(Alias())) = Upper(cDataBase)
         DbSelectArea(cDataBase)
         RETURN .T.
      ENDIF
   ENDIF
NEXT
DO CASE
CASE UPPER(cDataBase) = 'CADASTRO'
   IF !LETO_FILE(cServer+"CADASTRO.CDX")
      NetUse(cServer,cDataBase,.T.)   
      INDEX ON APTO   TAG CAD001
      INDEX ON SACADO TAG CAD002
      CADASTRO->(DbCloseArea())
   ENDIF
   IF !lExclusive
      NetUse(cServer,cDataBase,lExclusive)
   ENDIF
OTHERWISE
   Exclama('Arquivo: '+cDataBase+' não criado!')
ENDCASE
DbSelectArea(cDataBase)
RETURN .T.

Re: LetoDB - Problemas com DbCommit()

MensagemEnviado: 18 Out 2010 10:11
por alaminojunior
Assimões, obrigado pela resposta.
A maneira como eu abro os arquivos é praticamente igual a sua, sempre tomando os devidos cuidados.
Mas o problema é outro. Já testei se as duas aplicações estão abrindo o mesmo arquivo, e estão. Pois os executáveis e o arquivo ini que montei, são idênticos para ambos.

A rotina que postei de início assegura que dois ou mais pc´s não gerem pedidos com o mesmo número, e com dbfcdx sempre atendeu corretamente.
Porém com o uso do letodb, ela não funciona a contento. É como se cada estação tivesse o seu dbf único.
Na prática está acontecendo o seguinte:
o dbf guarda num campo o número do último pedido gerado, por exemplo 001234;
abro o executável nos dois pc´s;
se eu gerar um pedido novo no pc1, ele obedece a ordem, ou seja, gerando o pedido 001235;
se eu for no pc2, ele gera novo pedido com o número 001235 !!! como se o pc1 não tivesse commitado o dbf
e assim sucessivamente
Inclusive se eu for gerando pedidos no pc1, digamos até 002000, e o no pc2 o último gerado foi o 001235, se tentar gerar outro neste último pc, é gerado o 001236
É como se a variável que guarda este número nos terminais, não fosse atualizada com base no que existe no dbf.

Seguem os arquivos ini que ficam nas estações e servidor respectivamente.

[/code]
[SERVIDOR]
Servidor=//192.168.0.10:2812/
Dados=\Alamino\
Drive=C:
RDD=LETO


Port = 2812
DataPath = \c:\alamino
Logfile = "letodb.log"
Default_Driver = CDX
EnableFileFunc = 1
Crypt_Traffic = 1   

Função de abertura
[code]Function usa(arquivo,sh,ro)
If RddLeto
   If Leto_File(srv+arquivo+'.dbf')
      DbUseArea(.t.,"LETO",srv+arquivo+'.dbf',,sh,ro,'PTISO')
   Else
      MsgStop('Arquivo Não Foi Localizado: '+arquivo+'.dbf')
      return .f.
   EndIf
Else
   DbUseArea(.t.,'DBFCDX',arquivo,,sh,ro,'PTISO')
   if neterr()
      return .f.
   endif
EndIf
return .t.


Continuo dependendo da ajuda dos colegas.

Re: LetoDB - Problemas com DbCommit()

MensagemEnviado: 18 Out 2010 12:12
por asimoes
Alamino,

Você já tentou usar as funções:

leto_BeginTransaction()
leto_CommitTransaction()?

Re: LetoDB - Problemas com DbCommit()

MensagemEnviado: 18 Out 2010 12:33
por alaminojunior
Sim, já tentei conforme abaixo e também nada. Já tô ficando doido.
if orc = 0
   sele cdpar000
   leto_begintransaction() // coloquei por curiosidade
   do while .t.
      if !rlock()
          msgexclamation("Aguardando para criar novo orçamento ...","ATENÇÃO")
         loop
      else
          repl numnum with numnum+1
         //dbcommit() // tirei esta, mas já testei com ela junto e nada
         orc = numnum    // aqui parece que a variável orc não é atualizada com base no valor do campo do dbf
         leto_CommitTransaction() // idem
          dbunlock() ...


É incrível, mas dá a impressão que apesar dos dois pc´s abrirem o mesmo dbf, cada um segue a vida com uma cópia só para sí.
Mais uma vez obrigado pelo esforço.

Re: LetoDB - Problemas com DbCommit()

MensagemEnviado: 18 Out 2010 13:19
por ANDRIL
Alamino, não conheço esse LetoDB (me parece ser um servidor onde os DBFs ficam para acesso via rede/ip) seria isso?

Bom em se tratando de servidor de arquivo (base de dados) notei no seu post que é como se tivesse um dbf em cada pc, temporariamente. Ao exemplo do que acontece com os DATASET de outras linguagens, a cada solicitação a máquina cliente recebe uma cópia (parcial ou total) da tabela solicitada no servidor (veja, nao sei como funciona isso no LetoDB). Talvez seja por isso que esta sendo gerado o mesmo numero de pedido, sera que o dbcommit() nao esta atualizando a tabela temporaria do pc em questão?

Já verificou se tem alguma opção que fale sobre tabelas do lado do cliente, como update ou outro comando.

Veja se seu servidor esta com o gerencimento de cache de disco do windows, desativado, quem sabe pode mudar algo. Seria bom, alguem que tenha mais experiencia com essa ferramenta, ver se isso ocorre quando usando sistema em rede, ou se é só com voce mesmo.

Desculpe se compliquei ainda mais.
Boa sorte!

Re: LetoDB - Problemas com DbCommit()

MensagemEnviado: 18 Out 2010 13:36
por asimoes
Alamino,

Tem uma diferença na forma como você abre o dbf para a função em que eu abro o dbf, veja:
cServer='//192.168.0.1:2815/'
cDataBase:='NOMEDBF'

Atente que eu estou defindo o rdd "DBFCDX" AQUI
DBUseArea(.T.,,cServer+cDataBase,cDataBase,.F.,"DBFCDX") // essa é aminha forma.

Não sei se é o caso.

[]´s

Re: LetoDB - Problemas com DbCommit()

MensagemEnviado: 18 Out 2010 13:44
por asimoes
Alamino,

Tenta uma coisa, após gravar, fecha a tabela e abre novamente.

Re: LetoDB - Problemas com DbCommit()

MensagemEnviado: 18 Out 2010 13:51
por alaminojunior
Alamino, não conheço esse LetoDB (me parece ser um servidor onde os DBFs ficam para acesso via rede/ip) seria isso?
Isso mesmo.

Bom em se tratando de servidor de arquivo (base de dados) notei no seu post que é como se tivesse um dbf em cada pc, temporariamente. Ao exemplo do que acontece com os DATASET de outras linguagens, a cada solicitação a máquina cliente recebe uma cópia (parcial ou total) da tabela solicitada no servidor (veja, nao sei como funciona isso no LetoDB). Talvez seja por isso que esta sendo gerado o mesmo numero de pedido, sera que o dbcommit() nao esta atualizando a tabela temporaria do pc em questão?
Realmente é o que parece, neste caso específico. Como se dois ou mais clientes tivessem uma cópia do dbf e vivessem independentemente.
Interessante é que só acontece nesse caso, se eu appendar itens num dado orçamento, o outro cliente tem a atualização em tempo real. A diferença é que este dbf que guarda o último número de pedido, não é indexado. É um dbf de único registro onde guardo diversas outras flags e informações.

Agradeço a força e sigo neste dilema.

Re: LetoDB - Problemas com DbCommit()

MensagemEnviado: 18 Out 2010 13:59
por alaminojunior
asimoes escreveu:Alamino,
Tenta uma coisa, após gravar, fecha a tabela e abre novamente.

Testado meu caro, mas nada ainda. :'(
Atente que eu estou defindo o rdd "DBFCDX" AQUI
DBUseArea(.T.,,cServer+cDataBase,cDataBase,.F.,"DBFCDX") // essa é aminha forma.

Eu até podería abrir somente esta tabela via DBFCDX (o que resolvería), mas o que eu quería era abrir tudo via LETO.

Já mandei e-mail até para o Tiririca e nada.

Re: LetoDB - Problemas com DbCommit()

MensagemEnviado: 18 Out 2010 14:08
por alaminojunior
Opa !
DBUseArea(.T., ,cServer+cDataBase,cDataBase,.F.,"DBFCDX")

Mas seguindo o help do xHarbour, o RDD sería o 2º parâmetro.

Re: LetoDB - Problemas com DbCommit()

MensagemEnviado: 18 Out 2010 14:25
por asimoes
Alamino,

Da forma eu faço a abertura do dbf, até remotamente funciona. Como leto puro, realmente nunca tentei.

Re: LetoDB - Problemas com DbCommit()

MensagemEnviado: 18 Out 2010 14:48
por asimoes
Alamino,

Vi que em um dos exemplos do letodb a abertura de dbf é assim:

dbUseArea(.t.,, cPath + 'test2')

Verifique na pasta tests, fonte test_tr.

Re: LetoDB - Problemas com DbCommit()

MensagemEnviado: 18 Out 2010 15:07
por alaminojunior
Sim, no caso foi definido o LETO como padrão, e foram suprimidos alguns parâmetros.

Re: LetoDB - Problemas com DbCommit()

MensagemEnviado: 18 Out 2010 16:45
por ANDRIL
Alamino, tente isso para forçar o refresh do registro:

 repl numnum with numnum+1
dbcommit()
skip 0
orc = numnum   
dbunlock() ...

Ate+

Re: LetoDB - Problemas com DbCommit()

MensagemEnviado: 18 Out 2010 17:00
por alxsts
Olá!

Sinceramente nunca vi o Leto.

Chamou a minha atenção nos arquivos .INI onde um tem "RDD=LETO" e o outro "Default_Driver = CDX "

Re: LetoDB - Problemas com DbCommit()

MensagemEnviado: 18 Out 2010 17:13
por alaminojunior
ANDRIL escreveu:Alamino, tente isso para forçar o refresh do registro:

É meu caro ... já havia tentado isso também. E nada !
alxsts escreveu:Chamou a minha atenção nos arquivos .INI onde um tem "RDD=LETO" e o outro "Default_Driver = CDX "

Alex, a linha RDD=LETO é para o meu exe saber que é para se conectar via LETODB, caso contrário conecta via DBFCDX. Já a outra linha é do arquivo INI onde o motor do LetoDB identifica se utilizará o padrão CDX ou NTX.

A luta continua.

Re: LetoDB - Problemas com DbCommit()

MensagemEnviado: 18 Out 2010 17:33
por asimoes
Alamnino,

Você tentou simular este erro local, abrindo duas instancias do programa no windows?

Re: LetoDB - Problemas com DbCommit()

MensagemEnviado: 18 Out 2010 18:35
por asimoes
Alamino,

A solução é antes do RLOCK coloque um SKIP -1 ou DbSkip(-1) ou DbGoTop()

sele cdpar000
do while .t.
   DbGoTop() ou DbSkip(-1)
   if !rlock()
      msgexclamation("Aguardando para criar novo orçamento ...","ATENÇÃO")
      loop
   else
      repl numnum with numnum + ="posthilit">1</span>
      dbcommit()
      orc = numnum
      dbunlock()

Re: LetoDB - Problemas com DbCommit()

MensagemEnviado: 18 Out 2010 21:06
por alaminojunior
asimoes escreveu:A solução é antes do RLOCK coloque um SKIP -1 ou DbSkip(-1) ou DbGoTop()


Agora você derrubou a árvore inteira. :)) :)) :))

Usei um dbgotop(). Vai entender né !?
Assimoes e também Andril, obrigadíssimo pelo esforço.

Re: LetoDB - Problemas com DbCommit()

MensagemEnviado: 21 Out 2010 09:55
por alaminojunior
Então o danado estava dando um skip sem eu mandar ?

LetoDB - Problemas com DbCommit()

MensagemEnviado: 19 Jun 2018 22:55
por vddnet
Alamino, passei pela mesma dificuldade, não sei se já resolvei, mas a solução é esta

sele cdpar000
do while .t.
if !rlock()
msgexclamation("Aguardando para criar novo orçamento ...","ATENÇÃO")
loop
else
repl numnum with numnum + 1
Goto 1 // Adiciona somente esta linha no seu código fonte, levando em consideração que o banco de dados de número de pedido só tenha este registro, diga-me se teve exito
dbcommit()
orc = numnum
dbunlock()
* OBS.: Se já resolveu esta situação desconsidere este ajuda.