Hard commit ou algo assim

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

Moderador: Moderadores

Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Hard commit ou algo assim

Mensagem por JoséQuintas »

Ainda estou mexendo naquele aplicativo Clipper Summer, passando pra Harbour.
Tem uma coisa nele que acho péssimo pra programação, mas estou na dúvida sobre vantagem do uso.

Os arquivos são abertos/fechados muitas vezes durante o fonte.
Pensava que era por causa de limite de arquivos abertos, mas limita a um máximo de uns 5 arquivos abertos, somente aonde necessário.
Num caixa, por exemplo, a cada lançamento os arquivos são abertos/fechados.

É ambiente de rede, servidor com nobreak.
Mas no caixa se desligar o terminal, acabar a luz, ou coisa assim, só se perde o lançamento atual.
Se deixar os arquivos abertos, como depende do cache do sistema operacional, qualquer coisa pode se perder.
Muito mais seguro apenas se limitar ao último lançamento, ficando parecido com um SQL no que se refere a situação do terminal se desligar, ou ficar sem energia elétrica.

Mas trabalhar num fonte onde um arquivo pode ou não estar aberto é trabalhoso demais e perigoso.
Tem algo no Harbour que permita fazer esse "hard commit", pra salvar tudo pendente?

Alternativas que imaginei:
- Salvar/restaurar arquivo,índices,ordem e recno pra poder fechar e reabrir
- Usar uma única área pra abrir/fechar os mesmos arquivos nos append/replace - opção talvez mais interessante

exemplo da segunda alternativa:

Código: Selecionar todos

AbreArquivos( { "arquivo1", "arquivo2", "arquivo3" } )
...
...
nSelect := Select()
SELECT 0
USE arquivo2 ALIAS savedata
SET INDEX TO arquivo2
REPLACE 
USE
SELECT ( nSelectAnt )
Tem alguma coisa no Harbour que já garanta salvar tudo?

Obs.
É engraçado, mas como justificar a mudança de fonte para o que é certo, se do jeito atual pode-se perder apenas o último lançamento, mas se ficar em cache, pode-se perder qualquer coisa, um bloco com informações aleatórias.
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Avatar do usuário
Jairo Maia
Moderador
Moderador
Mensagens: 2785
Registrado em: 16 Ago 2010 13:46
Localização: Campinas-SP

Hard commit ou algo assim

Mensagem por Jairo Maia »

Jose, não seria isso que você quer?:

DbCommitAll() // Salva em disco todos os dados pendentes de todas as áreas abertas.
Description:
The DbCommitAll() function writes buffers of all work areas to disk. It performs the same operations as DbCommit(), except that all work areas with open databases are iterated in one function call.
Uso DbCommitAll() a cada final de lançamento, antes de enviar a impressora. Penso que é isso que você busca.
Abraços, Jairo
Harbour / Clipper 5.2e - Blinker 7
(Não respondo dúvidas por MP ou E-mail. Por favor, não encaminhe via mensagem privada ou e-mail, dúvidas que podem ser compartilhadas com todos no fórum)
vilian
Usuário Nível 1
Usuário Nível 1
Mensagens: 27
Registrado em: 29 Ago 2013 17:39
Localização: Belem/Pa

Hard commit ou algo assim

Mensagem por vilian »

Jose,

O DbCommitAll() não funciona, não garante de fato a atualização física dos arquivos e índices. Se usar o ADS (Advantage Database Server) utilize o AdsWriteAllRecords().
Avatar do usuário
janio
Colaborador
Colaborador
Mensagens: 1846
Registrado em: 06 Jul 2004 07:43
Localização: UBAJARA - CE

Hard commit ou algo assim

Mensagem por janio »

DbCommitAll() não funciona???

Taí uma baita novidade pra mim
fui...
e-mail:janioaguiar@yahoo.com.br
msn: janio_aguiar@hotmail.com
xHarbour1.2.1/Harbour3.2 + wvg + hwgui + Mediator + MySql
vilian
Usuário Nível 1
Usuário Nível 1
Mensagens: 27
Registrado em: 29 Ago 2013 17:39
Localização: Belem/Pa

Hard commit ou algo assim

Mensagem por vilian »

Janio,

Tive a mesma surpresa que vc quando descobri isso. Mas é verdade, e é bem fácil de vc constatar - Inclua um lançamento, execute o DbCommitAll() e logo após o comando, simule uma queda de energia, reiniciando o micro. Nos testes que fiz, o novo registro foi perdido.

Repetindo o mesmo teste, mas usando o AdsWriteAllRecords() ao invés do DbCommitAll(), o lançamento fica registrado.
Avatar do usuário
Jairo Maia
Moderador
Moderador
Mensagens: 2785
Registrado em: 16 Ago 2010 13:46
Localização: Campinas-SP

Hard commit ou algo assim

Mensagem por Jairo Maia »

Olá vilian,

Também fiquei surpreso com sua afirmação, e fiz os testes aqui, primeiro abrindo em rede, e na estação, deixei o browse aberto. Meu sistema faz um refresh a cada 10 segundos para exibir no browse os novos registros inseridos, e aparecem normalmente no browse, o que significa que foram salvos. Depois, no servidor coloquei um Quit após o DbCommitAll(), inseri um registro, obviamente o servidor abortou, e o registro apareceu normalmente na estação. Ao reiniciar o sistema no servidor, os registros haviam sido salvos.

Então fui verificar o fonte da função DbCommitAll(), que é:

Código: Selecionar todos

HB_FUNC( DBCOMMITALL )
{
   hb_rddFlushAll();
}
E da função hb_rddFlushAll() é (veja os comentarios):

Código: Selecionar todos

HB_EXPORT void hb_rddFlushAll( void )
{
   USHORT uiArea = hb_rddGetCurrentWorkAreaNumber(), uiIndex;    // Pega area atual

   for( uiIndex = 1; uiIndex < s_uiWaMax; ++uiIndex )            // inicia o laço para cada area aberta
   {
      hb_rddSelectWorkAreaNumber( s_WaList[ uiIndex ]->uiArea ); // seleciona uma a uma area aberta
      SELF_FLUSH( s_pCurrArea );                                 // salva os registros da area selecionada
   }
   hb_rddSelectWorkAreaNumber( uiArea );                         // volta a area que estava aberta
}
A Função hb_rddFlushAll() poderia simplesmente também ser escrita assim:

Código: Selecionar todos

Function SalvaTudo()
 Local cAlias := Alias(), nArea := 1
 While Select( nArea )
  If Used()
   DbCommit()
   nArea++
  Else
   Exit
  EndIf
 EndDo
 Select( cAlias )
Return Nil
Assim, não vejo motivo para não acreditar nessa função.
Abraços, Jairo
Harbour / Clipper 5.2e - Blinker 7
(Não respondo dúvidas por MP ou E-mail. Por favor, não encaminhe via mensagem privada ou e-mail, dúvidas que podem ser compartilhadas com todos no fórum)
Avatar do usuário
ANDRIL
Usuário Nível 5
Usuário Nível 5
Mensagens: 1299
Registrado em: 06 Jul 2004 00:44
Contato:

Hard commit ou algo assim

Mensagem por ANDRIL »

Jairo Maia escreveu:no servidor coloquei um Quit após o DbCommitAll()
Acho que o QUIT encerra todas as áreas abertas e encerra o que tem que ser encerrado, o que difere de uma queda de energia. Em se tratando de CACHE de DISCO tem que verificar como o Windows também esta tratando isso, já vi casos de gravar um registro e após uma reinicialização não estar mais devido ao bendito CACHE.

Vamos acompanhar...
Clipper 5.2e / Blinker 5.1 / Harbour 3.2 / GTwvg
Avatar do usuário
Jairo Maia
Moderador
Moderador
Mensagens: 2785
Registrado em: 16 Ago 2010 13:46
Localização: Campinas-SP

Hard commit ou algo assim

Mensagem por Jairo Maia »

Olá Pessoal,

Com base no que o Andril disse:
ANDRIL escreveu:Acho que o QUIT encerra todas as áreas abertas e encerra o que tem que ser encerrado
Fiz um novo teste trocando o Quit por Alert("ok"), e quando o alert apareceu, desconectei o cabo de energia do servidor (para simular uma queda real de energia). Na estação o registro apareceu (claro, após reiniciar o sistema), bem como no servidor. Porém, acho (destaco: acho) que isso pode ter algo a ver:
ANDRIL escreveu:Em se tratando de CACHE de DISCO tem que verificar como o Windows também esta tratando isso
Assim, como o Andril disse: Vamos acompanhar...

[Errata:]Onde se le na minha postagem anterior:
While Select( nArea ), leia: While Select( nArea ) != 0
Abraços, Jairo
Harbour / Clipper 5.2e - Blinker 7
(Não respondo dúvidas por MP ou E-mail. Por favor, não encaminhe via mensagem privada ou e-mail, dúvidas que podem ser compartilhadas com todos no fórum)
Avatar do usuário
ANDRIL
Usuário Nível 5
Usuário Nível 5
Mensagens: 1299
Registrado em: 06 Jul 2004 00:44
Contato:

Hard commit ou algo assim

Mensagem por ANDRIL »

Jairo, disse sobre o CACHE DE DISCO por que este problema de sumiço ocorre uma hora ou outra e geralmente com esta ativado este serviço no Windows. É uma possibilidade a ser testada.

Vamos ver!
Clipper 5.2e / Blinker 5.1 / Harbour 3.2 / GTwvg
Responder