Página 1 de 1

ainda o dbcommitall()

Enviado: 30 Mar 2005 09:53
por marcos.gurupi
O colega vagner me passou q o dbcommitall() faz a atualizacao/gravação de todas as areas abertas certo? Mas ai me surge uma outra pergunta, n seria preciso travar estes arquivos para eles sejam atualizados? Pois eu usava assim:

DO WHILE .T.
SELECT 1
IF TRAVARQIVO(5)
APPEND BLANK
REPLACE...
COMMIT
UNLOCK
ELSE
ATENC(19,10,"Contas a Receber sendo alterado no momento")
loop
endif
exit
enddo

Ou seja ateh o commit ele (arquivo) estava travado, isso tb n se aplica a dbcommitall()?

Obrigado.

Marcos Roberto.

Enviado: 30 Mar 2005 10:22
por evolver
Bem, segundo o ng tanto o commit quanto dbcommit() e dbcommitall() tem que ser executados antes de um unlock para poder atualizar decentemente o banco de dados.

Enviado: 30 Mar 2005 16:26
por marcos.gurupi
Ok mas se for o caso eu teria q travar todos os bd para q possa ser atualizados?

Tipo:

SELECT 1
do while .t.
IF TRAVARQIVO(5)
ELSE
LOOP
ENDIF
EXIT
ENDDO
SELECT 2
DO WHILE .T.
IF TRAVAQIVO(5)
ELSE
LOOP
ENDIF
EXIT
ENDDO
... E SOMENTE DEPOIS
DBCOMMITALL()
... ENTAUM REPETIR O PROCESSO SOH Q USANDO O UNLOCK.
SELECT 1
UNLOCK
SELECT 2
UNLOCK

... E COMO TENHO MAIS DE 50 ARQUIVOS ABERTO ISSO SERIA INVIAVEL...

Alguem tem alguma sugestão?

Enviado: 31 Mar 2005 04:47
por Dudu_XBase
Marcos Bom Dia !!
Como vc citou isso é totalmente inviável travar os arquivos para atualizar os buffers locais de apenas um usuário.
Imagine tenho 137 negos usando meu sistema hj na industria já pensou o cara do estoque precisa mudar a unidade de medida de um produto, uma alteração, vou parar todo mundo que usa esse dbf para executar um "commit"...ai é tornar seu sistema monousuário...
Lembrando que qdo o usuário acessa um determinado registro na rede ele recebe uma cópia dele que fica armazenado no seu buffer local.
Outro método de vc atualizar os buffers locais é depois de uma alteração vc fechar o dbf e abrir ele novamente.
Para que vc trava/bloqueia o registro ? Para não deixar q outro usuário da rede tenha acesso a gravação a ele, qdo vc trava ou bloqueia um registro, os demais usuários somente poderão ler (read) e somente vc que possui o registro bloqueado possuirá a gravação (write). Agora bloquear o arquivo todo já estou imaginando seus usuários te infernizando e hj vc sabe eles fazem isso mto bem.


Eu uso dessa forma qdo o usuário vai alterar um registro especifico...

While !rlock()
enddo
// os replaces
dbcommit()
dbunlock()

Eu faço uso do dbunlockall() e dbcommitall()...por questão de performance....qdo vários registros serão alterados...ou incluidos numa mesma procedure...
Tipo qdo vou executar um processo dentro de um laço ou vários laços da forma q colocarei abaixo..
Vou processar o banco fulano localizando no dbf ciclano e executando um replace..e tb alterando no dbf beltrano...

Código: Selecionar todos

  fulano->(dbgotop())
  While !fulano->(eof())
     if ciclano->(dbseek(fulano->CODIGO)
        while !ciclano->(rlock())
        enddo 
        // Meus Replaces
    endif

    if beltrano->(dbseek(fulano->CODIGO))
        while !beltrano->(rlock())
        enddo 
        // Meus Replaces
   endif
    
     fulano->(dbskip())
  enddo

  // Só agora vou atualizar os buffers e liberar os registros.
  dbcommitall()
  dbunlockall()

  

Enviado: 31 Mar 2005 09:35
por marcos.gurupi
Caro dudu_xbase, obrigado mais uma vez pelo esclarecimento, baseado no que vc, envolver e wagner me passou fiz uma funcao q ateh agora estah funcionando bem; Olha para que vcs entendem o meu problema vou explicar o pq dessas mudanças. Antes usava neste cliente um servidor w98, entaum ocorria muitas reindexacao durante o dia por motivo de corrupter detect, entaum pedi para q o cliente colocasse um servidor w2000 server, foi o q ele fez o sistema nunca tinha funcionado tao bem, mas havia um porem; quando alguem vazia uma venda ao balcao ou mesmo o pessoal do estoque atualizava o mesmo o sistema demorava a responder, era o "commit" no final de cada "replace..." comecei a pesquisar sobre o assunto e tirei o "commit" e adicionei o dbcommitall() no final de cada operação/procedure q executava o "replace" assim o sistema ficou rapido, mas voltou a corromper indixes com facilidade, ai entaum q fiz a funcao descrita logo abaixo:

...Eu gravo da seguinte maneira

Select 1
do while .t.
if travarqivo(5)
append blank
replace
unlock
else
atenc(19,10,"Arq. de contas a receber sendo alterado no momento.")
loop
endif
exit
enddo

...Ou altero assim

Select 1
do while .t.
if bloqueia(5)
replace
unlock
else
atenc(19,10,"Arq. de contas a receber sendo alterado no momento.")
loop
endif
exit
enddo

... Quando se trata por exemplo de uma venda ao balcao existem varios arq. que serao alterados ou mesmo registros serao adicionados, no final do processo eu executo a funcao:

GRAVATRAVALL()


FUNCTION GRAVATRAVALL()

PRIVATE TELATMP,AR001
SAVE SCREEN TO TELATMP
SHOW_red(10,19,13,55,"Aviso...")
contorno(11,19,13,55,2)
AR001:=SELECT()
DO WHILE .T.
@ 12,20 say "Aguarde... travando arquivos."
DO WHILE .T.
SELECT 1 // ARQUIVO DE CONTAS A RECEBER
if travarqivo(5)
else
loop
endif
exit
Enddo
DO WHILE .T.
SELECT 2 // ARQUIVO DE CLIENTES
if travarqivo(5)
else
loop
endif
exit
Enddo
DO WHILE .T.
SELECT 4 // ARQUIVO DE HISTORICO
if travarqivo(5)
else
loop
endif
exit
Enddo
DO WHILE .T.
SELECT 5 // ARQUIVO DE CAIXA
if travarqivo(5)
else
loop
endif
exit
Enddo
// FAÇO ISSO COM TODOS OS ARQUIVOS ABERTOS
@ 12,20 say "Aguarde... Gravando dados. "
dbcommitall()
dbunlockall()
EXIT
ENDDO
RESTORE SCREEN FROM TELATMP
SELECT(AR001)

Esse processo n leva alguns setessimo de segundos, ateh agora estah funcionando bem, mas lembro q alterei ontem vou ver o q acontece e depois posto aqui no forum. Obrigado!

Marcos Roberto

Enviado: 31 Mar 2005 09:36
por marcos.gurupi
Caro dudu_xbase, obrigado mais uma vez pelo esclarecimento, baseado no que vc, envolver e wagner me passou fiz uma funcao q ateh agora estah funcionando bem; Olha para que vcs entendem o meu problema vou explicar o pq dessas mudanças. Antes usava neste cliente um servidor w98, entaum ocorria muitas reindexacao durante o dia por motivo de corrupter detect, entaum pedi para q o cliente colocasse um servidor w2000 server, foi o q ele fez o sistema nunca tinha funcionado tao bem, mas havia um porem; quando alguem vazia uma venda ao balcao ou mesmo o pessoal do estoque atualizava o mesmo o sistema demorava a responder, era o "commit" no final de cada "replace..." comecei a pesquisar sobre o assunto e tirei o "commit" e adicionei o dbcommitall() no final de cada operação/procedure q executava o "replace" assim o sistema ficou rapido, mas voltou a corromper indixes com facilidade, ai entaum q fiz a funcao descrita logo abaixo:

...Eu gravo da seguinte maneira

Select 1
do while .t.
if travarqivo(5)
append blank
replace
unlock
else
atenc(19,10,"Arq. de contas a receber sendo alterado no momento.")
loop
endif
exit
enddo

...Ou altero assim

Select 1
do while .t.
if bloqueia(5)
replace
unlock
else
atenc(19,10,"Arq. de contas a receber sendo alterado no momento.")
loop
endif
exit
enddo

... Quando se trata por exemplo de uma venda ao balcao existem varios arq. que serao alterados ou mesmo registros serao adicionados, no final do processo eu executo a funcao:

GRAVATRAVALL()


FUNCTION GRAVATRAVALL()

PRIVATE TELATMP,AR001
SAVE SCREEN TO TELATMP
SHOW_red(10,19,13,55,"Aviso...")
contorno(11,19,13,55,2)
AR001:=SELECT()
DO WHILE .T.
@ 12,20 say "Aguarde... travando arquivos."
DO WHILE .T.
SELECT 1 // ARQUIVO DE CONTAS A RECEBER
if travarqivo(5)
else
loop
endif
exit
Enddo
DO WHILE .T.
SELECT 2 // ARQUIVO DE CLIENTES
if travarqivo(5)
else
loop
endif
exit
Enddo
DO WHILE .T.
SELECT 4 // ARQUIVO DE HISTORICO
if travarqivo(5)
else
loop
endif
exit
Enddo
DO WHILE .T.
SELECT 5 // ARQUIVO DE CAIXA
if travarqivo(5)
else
loop
endif
exit
Enddo
// FAÇO ISSO COM TODOS OS ARQUIVOS ABERTOS
@ 12,20 say "Aguarde... Gravando dados. "
dbcommitall()
dbunlockall()
EXIT
ENDDO
RESTORE SCREEN FROM TELATMP
SELECT(AR001)

Esse processo n leva alguns setessimo de segundos, ateh agora estah funcionando bem, mas lembro q alterei ontem vou ver o q acontece e depois posto aqui no forum. Obrigado!

Marcos Roberto