Como utilizar Begin Sequence e Try

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

Moderador: Moderadores

carlos_dornelas
Usuário Nível 3
Usuário Nível 3
Mensagens: 400
Registrado em: 25 Ago 2004 21:54

Como utilizar Begin Sequence e Try

Mensagem por carlos_dornelas »

Caros, estou precisando implementar uma rotina que me dê muita segurança para atualizar alguns dbfs sequencialmente. Tipo, se no meio do caminho algo inesperado acontecer, que as alterações iniciadas envolvendo atualização de registros e adição de novos registros, sejam desfeitas automaticamente. Será isso possível utilizando os controles abaixo ou através de outras funções? Alguém teria algum exemplo simples de utilização desses controles?

Grato

Antonio Carlos
Curitiba


BEGIN SEQUENCE
<statements_Normal>

[ BREAK [<expression>] ]

[ RECOVER [USING <errorVar>]
<statements_Error>
]
END[SEQUENCE]



TRY
<statements>
[THROW( <oErrorObject> )]
[CATCH [<thrownError>]
<errorHandling>
[FINALLY
<guaranteed> ]
END
carlos_dornelas
Usuário Nível 3
Usuário Nível 3
Mensagens: 400
Registrado em: 25 Ago 2004 21:54

Como utilizar Begin Sequence e Try

Mensagem por carlos_dornelas »

O pessoal, dá uma força aí...
Avatar do usuário
Pablo César
Usuário Nível 7
Usuário Nível 7
Mensagens: 5312
Registrado em: 31 Mai 2006 10:22
Localização: Curitiba - Paraná

Como utilizar Begin Sequence e Try

Mensagem por Pablo César »

para atualizar alguns dbfs sequencialmente. Tipo, se no meio do caminho algo inesperado acontecer, que as alterações iniciadas envolvendo atualização de registros e adição de novos registros, sejam desfeitas automaticamente
Apenas minha opinião. Acredito que esse recurso a base de dados em dbf não possui DTL - Linguagem de Transação de Dados como o SQL por exemplo. Portanto, qualquer rotina do tipo ROLLBACK, deve ser feito de forma artesanal e o seu funcionamento seria totalmente diferente como é dado num SGBD.
Um clip-abraço !

Pablo César Arrascaeta
Compartilhe suas dúvidas e soluções com todos os colegas aqui do fórum.
Evite enviar as dúvidas técnicas por MPs ou eMails, assim todos iremos beneficiar-nos.
alxsts
Colaborador
Colaborador
Mensagens: 3092
Registrado em: 12 Ago 2008 15:50
Localização: São Paulo-SP-Brasil

Como utilizar Begin Sequence e Try

Mensagem por alxsts »

Olá!

Carlos, você até pode utilizar estes blocos de comandos citados mas, isso sozinho não vai resolver o teu problema. Funcionaria muito bem em um banco de dados relacional, que não é o caso dos DBFs, onde uma transaction poderia ser aberta. Se todos os passos do processo fossem concluídos (Try), você encerraria com um commit. Caso contrario (Catch) você emitiria um rollback.

No caso presente, sugiro que você use o tradicional conceito de balance line. Neste tipo de processamento, você tem o arquivo de entrada (que é o teu DBF original), o arquivo de movimentações (inclusões,alterações e exclusões a serem feitas) e o arquivo de saída, que nada mais é que o arquivo original atualizado com as movimentações. Se algo der errado, é só reprocessar.

Mais dúvidas? Continue postando.
[]´s
Alexandre Santos (AlxSts)
Avatar do usuário
Pablo César
Usuário Nível 7
Usuário Nível 7
Mensagens: 5312
Registrado em: 31 Mai 2006 10:22
Localização: Curitiba - Paraná

Como utilizar Begin Sequence e Try

Mensagem por Pablo César »

Só para complementar, adicionando mais uma ideia. Para o caso do bd ser dbfs, talvez no caso de persistência seja mais coerente fazer uma rotina de verificação do registro que foi gravado comparando com a rotina de verificação de integridade dos dados gravados, utilizando-se por exemplo do MD5 (como o colega Maligno já sugeriu há tempo atrás), veja: https://pctoledo.org/forum/viewto ... md5#p25469
Um clip-abraço !

Pablo César Arrascaeta
Compartilhe suas dúvidas e soluções com todos os colegas aqui do fórum.
Evite enviar as dúvidas técnicas por MPs ou eMails, assim todos iremos beneficiar-nos.
carlos_dornelas
Usuário Nível 3
Usuário Nível 3
Mensagens: 400
Registrado em: 25 Ago 2004 21:54

Como utilizar Begin Sequence e Try

Mensagem por carlos_dornelas »

Colegas, grato pelas dicas! achei interessantea ideia do balance line, pois me pareceu ser bem facil implementar no meu caso. Mas soh me resta a duvida quantos aos comandos objeto deste topico. Em que casos seria interessante utiliza-los (interrogacao)
Avatar do usuário
ANDRIL
Usuário Nível 5
Usuário Nível 5
Mensagens: 1298
Registrado em: 06 Jul 2004 00:44
Contato:

Como utilizar Begin Sequence e Try

Mensagem por ANDRIL »

Voce poderia antes de iniciar o processo de atualização, fazer uma copia do dbf que ira modificar. Abra o dbf em modo exclusivo ou em fLock() e faça a copia e salve também os índices desse arquivo. Rode a sua rotina de atualizacao dentro do TRY/CATCH se ocorrer um erro, voce volta o arquivo copia para original junto com seus índices.
Faça um teste e veja se fica viável.
Abraços
Clipper 5.2e / Blinker 5.1 / Harbour 3.2 / GTwvg
carlos_dornelas
Usuário Nível 3
Usuário Nível 3
Mensagens: 400
Registrado em: 25 Ago 2004 21:54

Como utilizar Begin Sequence e Try

Mensagem por carlos_dornelas »

Andril, grato pela sua dica. Eu ja tinha pensado no backup dos dbfs antes de iniciar o processo. Então voltamos para o IF ELSE ENDIF, não?
Avatar do usuário
ANDRIL
Usuário Nível 5
Usuário Nível 5
Mensagens: 1298
Registrado em: 06 Jul 2004 00:44
Contato:

Como utilizar Begin Sequence e Try

Mensagem por ANDRIL »

carlos_dornelas escreveu:Então voltamos para o IF ELSE ENDIF, não?
Amigo não entendi o que quiz dizer. Mas, pode usar o TRY/CATCH sem IF mesmo. Veja este exemplo:

Código: Selecionar todos

priv arqs:{{"clientes.atu","clientes.dbf","clientes.res"},;
                {"produtos.atu","produtos.dbf","produtos.res"},;
                {"fornece.atu","fornece.dbf","fornece.res"};
                }
For i = 1 to len(arqs)
  *| faz a copia do arquivo dbf a ser tratado
  COPY FILE arqs[i,1] TO arqs[i,3] 
 
  TRY
     SuaRotinadeAtualizacao(arqs[i,1],arqs[i,2])
    
  CATCH
     |* se ocorreu um erro, Restaura o arquivo reserva 
     COPY FILE arqs[i,3] TO arqs[i,1]
  END
  |* aqui se quiser pode apagar o arquivo reserva
  ferase(arqs[i,3]) 

Next
Amigo, algumas consideracoes:

- tratei cada dbf individualmente, o ideal seria voce ter os indices desses dbfs pois no caso de
erro voce voltaria o reserva e recriava os indices para nao dar problema de corrupção. Este procedimento
pode ser deixado de lado, se voce abrir os dbf em modo EXCLUSIVO sem abertura dos indices, assim, os
indices nao seriam atualizados durante a atualizacao, ficando compativel com a copia reserva. Neste
caso, ao voltar a copia reserva basta reabrir os indices.

- este é um exemplo simplório, apenas para ter uma idéia.

Até+
Clipper 5.2e / Blinker 5.1 / Harbour 3.2 / GTwvg
carlos_dornelas
Usuário Nível 3
Usuário Nível 3
Mensagens: 400
Registrado em: 25 Ago 2004 21:54

Como utilizar Begin Sequence e Try

Mensagem por carlos_dornelas »

Andril,

Com relação ao IF ELSE ENDIF, pensei no seguinte:

Código: Selecionar todos

Sucesso=0
MinhaFuncaoAtualiza()
**se houver algum problema, altero o valor de Sucesso=1

IF sucesso=0
   OK, segue o programa
ELSE
   DESFAZ, e retorna
ENDIF
Avatar do usuário
ANDRIL
Usuário Nível 5
Usuário Nível 5
Mensagens: 1298
Registrado em: 06 Jul 2004 00:44
Contato:

Como utilizar Begin Sequence e Try

Mensagem por ANDRIL »

Entendi, de qualquer forma para que voce possa alterar o conteudo da variavel Sucesso voce tera que usar uma estrutura de controle de erro como a TRY/CATH. Dependendo que como voce monte a sua funcao de atualizacao (processar um a um ou todos e reportar um erro) pode ser significativo a forma como postei acima.
Estude o método que seja mais viável pois voce tem o codigo e a lógica do negócio.
Boa sorte.
Clipper 5.2e / Blinker 5.1 / Harbour 3.2 / GTwvg
carlos_dornelas
Usuário Nível 3
Usuário Nível 3
Mensagens: 400
Registrado em: 25 Ago 2004 21:54

Como utilizar Begin Sequence e Try

Mensagem por carlos_dornelas »

Andril, só uma última dúvida: no teu exemplo, você escreveu: " se ocorreu um erro, Restaura o arquivo reserva". Esse "erro" seria um erro de programa, daqueles que causa o encerramento do programa? Se é isso, começo a perceber a vantagem do TRY CATCH...
Avatar do usuário
ANDRIL
Usuário Nível 5
Usuário Nível 5
Mensagens: 1298
Registrado em: 06 Jul 2004 00:44
Contato:

Como utilizar Begin Sequence e Try

Mensagem por ANDRIL »

carlos_dornelas escreveu:Se é isso, começo a perceber a vantagem do TRY CATCH...
É isso ai. Esta é a vantagem desta estrutura. Ela monitora o run-time, quando o codigo entre TRY e CATH ocasiona um erro, gera uma "Exception" como diz em outras linguagens. Em outra estrutura como if, case por exemplo, ocorreria o erro e o programa seria abortado.

Vá treinando fazendo testes e logo voce dominará.
Abraços
Clipper 5.2e / Blinker 5.1 / Harbour 3.2 / GTwvg
Stanis Luksys
Colaborador
Colaborador
Mensagens: 1329
Registrado em: 18 Jun 2005 03:04
Localização: São Paulo
Contato:

Como utilizar Begin Sequence e Try

Mensagem por Stanis Luksys »

Olá,

Depende do tamanho dos arquivos e o quanto eles são usados na rede. A forma mais simples que eu conheço de fazer isso, e que eu já usei com Harbour, foi a seguinte.

1 - Abre todos os DBFs envolvidos em modo exclusivo
2 - Abre o TRY e para cada DBF, antes de atualizar, faz o backup dele com FCopy ou COPY TO, e guarda só o nome dele numa matriz.
3 - Se der algum erro, varre a matriz restaurando os DBFS que foram alterados. Os que não foram alterados, não estarão na matriz. Tudo volta ao normal.

Uma outra forma, seria criar vários DBFs vazios com estruturas iguais aos originais (COPY STRUCTURE EXTENDED), e neste vazios apenas incluir o registro que foi alterado no original, como ele era antes da alteração. Se der erro, delete os que foram alterados e traz estes de volta.

Este segundo método é melhor pois não precisa abrir exclusivo, e não precisa fazer backup dos arquivos inteiros, o que atrapalharia em casos de DBFS grandes.

Abraços.
Stanis Luksys
sites.google.com/hblibs

Apoiar e se utilizar de projetos opensource não é uma questão de boicote, mas sim de liberdade.
Utilize, aprimore e distribua.
Responder