ainda o dbcommitall()

Fórum sobre a linguagem CA-Clipper.

Moderador: Moderadores

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

ainda o dbcommitall()

Mensagem 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.
evolver
Membro Master
Membro Master
Mensagens: 189
Registrado em: 28 Ago 2004 01:02
Localização: Cruz Alta - RS
Contato:

Mensagem 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.
Sergio "Evolver" Fagundes

CURVE-SE DIANTE DE MIM SER INSIGNIFICANTE, POIS EU SOU ROOT
Só respondo em PVT perguntas relativas ao que eu faço. Qualquer outra dúvida favor postar no fórum.
Peço aos veteranos que antes de responder a uma pergunta repetida dêem uma pesquisada e instruam a quem perguntou a fazer o mesmo.
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

Mensagem 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?
Dudu_XBase
Membro Master
Membro Master
Mensagens: 1071
Registrado em: 25 Ago 2003 16:55

Mensagem 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()

  


________________________________________________________________________________________________________
(Aow Saudade) Clipper 5.2e, Blinker 7, RDD SIXNSX, DBFCDX /Xharbour 1.0, Rdd Mediator (Mysql) Free , RDD Sqlrdd (Sql Server) Comercial
(Hoje) C# Python Sql Server e Oracle




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

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

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