1. This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn More.

  2. Anuncie Aqui ! Entre em contato fdantas@4each.com.br

Duvida Liberar Transaction

Discussão em 'Progress 4GL' iniciado por Alexandre, Maio 12, 2021.

  1. Alexandre

    Alexandre Membro Participativo

    Código:
    MESSAGE Transaction
        VIEW-AS ALERT-BOX INFO BUTTONS OK.
    
    FIND FIRST ITEM EXCLUSIVE-LOCK NO-ERROR.
    
    
    FIND CURRENT ITEM NO-LOCK NO-ERROR.
    RELEASE ITEM.
    LEAVE Transaction.
    
    MESSAGE TRANSACTION
        VIEW-AS ALERT-BOX INFO BUTTONS OK.

    Boa tarde Pessoal alguém sabe como liberar uma transação?
  2. rafael.andrade

    rafael.andrade Membro Master Moderador Equipe de Suporte

    Você precisa delimitar quando começa uma transação e quando termina, segue abaixo o bloco perfeito para se fazer uma transação.

    Código:
    
    DEF TEMP-TABLE ttMsg   NO-UNDO /* Tabela para armazenar os erros do sistema, NO-UNDO é essencial para não excluir registros ao desfazer transação */
             FIELD Tipo AS INTEGER
             FIELD Cod  AS INTEGER
             FIELD Msg  AS CHAR.
             
    /* ##### EXIBE AS MENSAGENS GRAVADAS ######################################################################################### */
    PROCEDURE ExibirMensagens.
       FOR EACH ttMsg NO-LOCK.
           DEF VAR Mensagem AS CHAR.
           IF ttMsg.Cod <> 0 THEN Mensagem = "(" + STRING(ttMsg.Cod) + ") - " + ttMsg.Msg.
           ELSE Mensagem = ttMsg.Msg.
           IF ttMsg.tipo = 1 THEN DO: /* INFORMAÇÃO */
              MESSAGE Mensagem
                      VIEW-AS ALERT-BOX INFO BUTTONS OK TITLE "Informação".
           END.
           ELSE IF ttMsg.tipo = 2 THEN DO: /* WARNING */
              MESSAGE Mensagem
                      VIEW-AS ALERT-BOX WARNING BUTTONS OK TITLE "Alerta".
           END.
           ELSE IF ttMsg.tipo = 3 THEN DO: /* ERRO */
              MESSAGE Mensagem
                      VIEW-AS ALERT-BOX ERROR BUTTONS OK TITLE "Erro Crítico".
           END.
       END.
       EMPTY TEMP-TABLE ttMsg.
    END PROCEDURE.
    /* ########################################################################################################################## */
    
    /* ####### CRIA UMA NOVA MENSAGEM ########################################################################################### */
    PROCEDURE CriaMsg.
      DEF INPUT PARAMETER vTipo AS INTEGER.
      DEF INPUT PARAMETER vCod AS INTEGER.
      DEF INPUT PARAMETER vMsg AS CHAR.
      CREATE ttMsg.
      ASSIGN ttMsg.tipo = vTipo
             ttMsg.cod  = vCod
             ttMsg.Msg  = vMsg.
    END PROCEDURE.
    /* ########################################################################################################################## */
    
    [FAZER TODAS AS VALIDAÇÕES ANTES DA TRANSAÇÃO, TUDO COM NO-LOCK EXPLÍCITO]
    
    DEF VAR EstaOK AS LOGICAL.
    
    TMaior:
    DO TRANS:
       DO ON QUIT UNDO TMaior, LEAVE:  /* ON QUIT E ON STOP FORÇAM O SERVIDOR A DESFAZER SE O SERVIDOR CAIR OU O USUÁRIO PERDER A CONEXÃO */
          DO ON STOP UNDO TMaior, LEAVE:
              DO ON ERROR UNDO TMaior, LEAVE:
             
                 FIND FIRST minhaTabela WHERE minhaTabela.id = 123456 EXCLUSIVE-LOCK NO-ERROR. /* Bloqueia o registro para alteração */
                 
                [Se precisar exibir mensagem, salve na TEMP-TABLE para exibir depois da transação, pois MESSAGE bloqueia a transação e o registro fica bloqueado até alguém clicar na mensagem]
                IF NOT AVAIL minhaTabela THEN DO:
                    RUN CriaMsg(3,10,"Transação desfeita pois o registro não foi encontrado!").
                    UNDO TMaior, LEAVE. /* DESFAZ A TRANSAÇÃO (ROLLBACK) e o LEAVE faz pular para o final, não use RETURN */
                 END.
                 
                ASSIGN minhaTabela.meuCampo = "ABC".
                 
                FIND CURRENT minhaTabela NO-LOCK NO-ERROR. /* Libera o registro depois que transação terminar */
                 
                EstaOK = TRUE. /* Variável para se verificar que tudo foi realizado com sucesso */
             
              END.
          END.
       END.
    END.
    
    IF EstaOK THEN DO:
       MESSAGE "Sucesso!" VIEW-AS ALERT-BOX INFO BUTTONS OK TITLE "Informação".
    END.
    
    RUN ExibirMensagens. /* Vai exibir todas mensagens que ocorreram dentro da transação */
    
    
    IMPORTANTE: O código acima foi feito de memória, não verifiquei sintax e pode ter algum erro.
  3. rafael.andrade

    rafael.andrade Membro Master Moderador Equipe de Suporte

    A temp-table ttMsg e as procedures, seria bom colocar numa include pra reutilizar em todos os programas.

    O Cabeçalho e Rodapé da Transação também poderia ser colocado em Includes, vai de cada gosto.

    Exemplo:
    Código:
    {includes\abrir-transacao.i}
    
    [MEU CÓDIGO]
    
    {includes\fechar-transacao.i}
    
    Onde a include {includes\abrir-transacao.i} teria:
    TMaior:
    DO TRANS:
    DO ON QUIT UNDO TMaior, LEAVE: /* ON QUIT E ON STOP FORÇAM O SERVIDOR A DESFAZER SE O SERVIDOR CAIR OU O USUÁRIO PERDER A CONEXÃO */
    DO ON STOP UNDO TMaior, LEAVE:
    DO ON ERROR UNDO TMaior, LEAVE:

    e a include {includes\fechar-transacao.i} teria todos os END de cada DO aberto.
  4. Alexandre

    Alexandre Membro Participativo

    rafael.andrade curtiu isso.
  5. bootstrapmaster

    bootstrapmaster Moderator Moderador Equipe de Suporte

    Vc não encerra uma transação, mas sim vc pode diminuir o escopo para atender as suas necessidades, ou seja, vc tem que fazer um do transaction: processar o que precisa, e depois do end. a regra do progress é simples, onde ele deduzir que pode haver um IO será um bloco de transação, logico, quando vc não declarar um, se vc declarar do transaction, um dentro do outro, vale o bloco mais externo, então essa regra pode ser problemas em caso de EPC ou UPC, porque vc não sabe se o programa chamador criou já uma transação, então é isso, sempre que possivel, declare um do transaction, faça seu IO dentro desse bloco, mas sempre faça isso no nivel mais detalhado, pra não travar toda a aplicação, porque blocos de transação envolve o fato de que tudo que acontecer dentro desse bloco fica preso, caso aconteça um erro, automaticamente acontece um UNDO, e perde tudo que estava na transação, lembro de um caso, nas primeiras versões do produto EMS2 da datasul, em que tinha um LOG de acesso no menu, eles não cuidaram essa questão, e o bloco de transação ficou ao nivel do menu, usuarios perdiam horas de trabalho porque dava um erro qualquer em um programa e desfazia tudo que tinha processado naquela sessão.
    Alexandre curtiu isso.

Compartilhe esta Página