LetoDB - Problemas com DbCommit()

Fórum sobre Banco de Dados e RDDs para Clipper/[x]Harbour.

Moderador: Moderadores

Avatar do usuário
alaminojunior
Colaborador
Colaborador
Mensagens: 1717
Registrado em: 16 Dez 2005 21:26
Localização: Ubatuba - SP

LetoDB - Problemas com DbCommit()

Mensagem por alaminojunior »

Estou fazendo um trabalho aqui com LetoDB, e me deparei com o seguinte:
Numa rotina de numeração de pedidos.

Código: Selecionar todos

   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:

Código: Selecionar todos

REQUEST LETO
RDDSETDEFAULT( "LETO" )
Para abrir o dbf eu uso:

Código: Selecionar todos

use &arquivo shared new
Onde arquivo é: //192.168.0.10:2812/ + nome do arquivo sem extensão
Compilador xHarbour 1.2.3 + Embarcadero C++ 7.30
MySQL c/ SQLRDD
HwGui + GTWVG
Avatar do usuário
asimoes
Colaborador
Colaborador
Mensagens: 4919
Registrado em: 26 Abr 2007 16:48
Localização: RIO DE JANEIRO-RJ

Re: LetoDB - Problemas com DbCommit()

Mensagem por asimoes »

Alamino eu faço assim:

Código: Selecionar todos

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

Código: Selecionar todos

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.)

Código: Selecionar todos

#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.
►Harbour 3.x | Minigui xx-x | HwGui◄
Pense nas possibilidades abstraia as dificuldades.
Não corrigir nossas falhas é o mesmo que cometer novos erros.
A imaginação é mais importante que o conhecimento. (Albert Einstein)
Avatar do usuário
alaminojunior
Colaborador
Colaborador
Mensagens: 1717
Registrado em: 16 Dez 2005 21:26
Localização: Ubatuba - SP

Re: LetoDB - Problemas com DbCommit()

Mensagem 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]

Código: Selecionar todos

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

Código: Selecionar todos

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.
Compilador xHarbour 1.2.3 + Embarcadero C++ 7.30
MySQL c/ SQLRDD
HwGui + GTWVG
Avatar do usuário
asimoes
Colaborador
Colaborador
Mensagens: 4919
Registrado em: 26 Abr 2007 16:48
Localização: RIO DE JANEIRO-RJ

Re: LetoDB - Problemas com DbCommit()

Mensagem por asimoes »

Alamino,

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

leto_BeginTransaction()
leto_CommitTransaction()?
►Harbour 3.x | Minigui xx-x | HwGui◄
Pense nas possibilidades abstraia as dificuldades.
Não corrigir nossas falhas é o mesmo que cometer novos erros.
A imaginação é mais importante que o conhecimento. (Albert Einstein)
Avatar do usuário
alaminojunior
Colaborador
Colaborador
Mensagens: 1717
Registrado em: 16 Dez 2005 21:26
Localização: Ubatuba - SP

Re: LetoDB - Problemas com DbCommit()

Mensagem por alaminojunior »

Sim, já tentei conforme abaixo e também nada. Já tô ficando doido.

Código: Selecionar todos

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.
Compilador xHarbour 1.2.3 + Embarcadero C++ 7.30
MySQL c/ SQLRDD
HwGui + GTWVG
Avatar do usuário
ANDRIL
Usuário Nível 5
Usuário Nível 5
Mensagens: 1297
Registrado em: 06 Jul 2004 00:44
Contato:

Re: LetoDB - Problemas com DbCommit()

Mensagem 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!
Clipper 5.2e / Blinker 5.1 / Harbour 3.2 / GTwvg
Avatar do usuário
asimoes
Colaborador
Colaborador
Mensagens: 4919
Registrado em: 26 Abr 2007 16:48
Localização: RIO DE JANEIRO-RJ

Re: LetoDB - Problemas com DbCommit()

Mensagem 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
►Harbour 3.x | Minigui xx-x | HwGui◄
Pense nas possibilidades abstraia as dificuldades.
Não corrigir nossas falhas é o mesmo que cometer novos erros.
A imaginação é mais importante que o conhecimento. (Albert Einstein)
Avatar do usuário
asimoes
Colaborador
Colaborador
Mensagens: 4919
Registrado em: 26 Abr 2007 16:48
Localização: RIO DE JANEIRO-RJ

Re: LetoDB - Problemas com DbCommit()

Mensagem por asimoes »

Alamino,

Tenta uma coisa, após gravar, fecha a tabela e abre novamente.
►Harbour 3.x | Minigui xx-x | HwGui◄
Pense nas possibilidades abstraia as dificuldades.
Não corrigir nossas falhas é o mesmo que cometer novos erros.
A imaginação é mais importante que o conhecimento. (Albert Einstein)
Avatar do usuário
alaminojunior
Colaborador
Colaborador
Mensagens: 1717
Registrado em: 16 Dez 2005 21:26
Localização: Ubatuba - SP

Re: LetoDB - Problemas com DbCommit()

Mensagem 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.

Código: Selecionar todos

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.
Compilador xHarbour 1.2.3 + Embarcadero C++ 7.30
MySQL c/ SQLRDD
HwGui + GTWVG
Avatar do usuário
alaminojunior
Colaborador
Colaborador
Mensagens: 1717
Registrado em: 16 Dez 2005 21:26
Localização: Ubatuba - SP

Re: LetoDB - Problemas com DbCommit()

Mensagem 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.
Compilador xHarbour 1.2.3 + Embarcadero C++ 7.30
MySQL c/ SQLRDD
HwGui + GTWVG
Avatar do usuário
alaminojunior
Colaborador
Colaborador
Mensagens: 1717
Registrado em: 16 Dez 2005 21:26
Localização: Ubatuba - SP

Re: LetoDB - Problemas com DbCommit()

Mensagem por alaminojunior »

Opa !
DBUseArea(.T., ,cServer+cDataBase,cDataBase,.F.,"DBFCDX")
Mas seguindo o help do xHarbour, o RDD sería o 2º parâmetro.
Compilador xHarbour 1.2.3 + Embarcadero C++ 7.30
MySQL c/ SQLRDD
HwGui + GTWVG
Avatar do usuário
asimoes
Colaborador
Colaborador
Mensagens: 4919
Registrado em: 26 Abr 2007 16:48
Localização: RIO DE JANEIRO-RJ

Re: LetoDB - Problemas com DbCommit()

Mensagem por asimoes »

Alamino,

Da forma eu faço a abertura do dbf, até remotamente funciona. Como leto puro, realmente nunca tentei.
►Harbour 3.x | Minigui xx-x | HwGui◄
Pense nas possibilidades abstraia as dificuldades.
Não corrigir nossas falhas é o mesmo que cometer novos erros.
A imaginação é mais importante que o conhecimento. (Albert Einstein)
Avatar do usuário
asimoes
Colaborador
Colaborador
Mensagens: 4919
Registrado em: 26 Abr 2007 16:48
Localização: RIO DE JANEIRO-RJ

Re: LetoDB - Problemas com DbCommit()

Mensagem 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.
►Harbour 3.x | Minigui xx-x | HwGui◄
Pense nas possibilidades abstraia as dificuldades.
Não corrigir nossas falhas é o mesmo que cometer novos erros.
A imaginação é mais importante que o conhecimento. (Albert Einstein)
Avatar do usuário
alaminojunior
Colaborador
Colaborador
Mensagens: 1717
Registrado em: 16 Dez 2005 21:26
Localização: Ubatuba - SP

Re: LetoDB - Problemas com DbCommit()

Mensagem por alaminojunior »

Sim, no caso foi definido o LETO como padrão, e foram suprimidos alguns parâmetros.
Compilador xHarbour 1.2.3 + Embarcadero C++ 7.30
MySQL c/ SQLRDD
HwGui + GTWVG
Avatar do usuário
ANDRIL
Usuário Nível 5
Usuário Nível 5
Mensagens: 1297
Registrado em: 06 Jul 2004 00:44
Contato:

Re: LetoDB - Problemas com DbCommit()

Mensagem por ANDRIL »

Alamino, tente isso para forçar o refresh do registro:

Código: Selecionar todos

 repl numnum with numnum+1
 dbcommit() 
 skip 0
 orc = numnum   
 dbunlock() ...
Ate+
Clipper 5.2e / Blinker 5.1 / Harbour 3.2 / GTwvg
Responder