Boa práticas na busca e manipulação de tabelas

Segue um rascunho de boas praticas na manipulação de tabelas em processos.

Primeiro de tudo, é sempre bom colocar sempre manipulações de tabelas em transações como no exemplo a seguir:

DO ON STOP UNDO, LEAVE:
  FIND FIRST <tablename> EXCLUSIVE-LOCK.
END.

Para ter uma maior controle em uma transação é possível criar uma transação customizada para manipular de acordo com possíveis falhas, se exemplo a seguir é criada uma transação denominada “Grava“.

Como a intenção é não interromper o processo, ao ocorrer um erro não dará a mensagem de erro, será chamada uma outra procedure “registraErro” que vai registrar o erro em arquivo ou mandar e-mail dependendo da necessidade.

Grava:
DO TRANS ON ERROR UNDO Grava, LEAVE Grava :
    /*Vai buscar o registro dando pegando para manipular sem registrar qualquer erro */
    FIND FIRST <tabela> EXCLUSIVE-LOCK NO-WAIT NO-ERROR.

    /* Verifica se a tabela esta travada por outro usuário, se estiver saí da transação */
    IF LOCKED(<tabela>) THEN DO:
        registraErro("Tabela em uso").
        UNDO Grava, LEAVE Grava.
    END.

    ASSIGN <tabela>.<campo> = <valor>.

    /* Faz validação da integridade dos dados na tabela */
    VALIDATE <tabela>.


    /* Se tiver algum erro registrado, desfaz as alterações realizadas e saí da transação */
    IF ERROR-STATUS:ERROR THEN DO:
        registraErro(ERROR-STATUS:GET-MESSAGE[1]).
        UNDO Grava, LEAVE Grava.
    END.

    /* Muito importante, executar um release para liberar a tabela,
       (não dar o famoso erro de tabela em uso por fulano) */
    RELEASE <tabela> NO-ERROR.

    /* Mais uma verificação se existe algum erro na transação*/
    CATCH eSysError AS Progress.Lang.SysError: 
        registraErro(eSysError:GetMessage(1)).
    END CATCH.
END. /* Grava */

Outra dica boa é saber a forma correta de fazer a busca de uma tabela:

FIND FIRST: Um FIND FIRST vai direto no primeiro registro e a tabela passa a ficar disponível depois da busca más não é tão bom com múltiplos índices, recomentado em tabelas simples ou tabelas temporárias.

FIND FIRST <tabela> NO-LOCK NO-ERROR.

FOR FIRST: Também trás o primeiro registro que encontrar na tabela, a vantagem sobre o FIND FIRST é de poder usar ordenação de registro ORDER BY, assim o primeiro que encontrar pode ser mesmo o primeiro que o usuário busca.

Existem duas possibilidades de uso do FOR FIRST que ao alterar entre “:” ou “.” no final da condição muda o seu comportamento. Se usar dois pontos “:“, o transforme em uma transação e os registros existem dentro desta transação. Quando usa apenas ponto “.” ele se comporta como o FIND FIRST e o registro localizado existe após sua execução.

FOR FIRST é recomentado em tabelas maiores ou complexas onde podem ser aplicados diversos índices.

/* FOR FIRST como transação */
FOR FIRST <tabela> NO-LOCK:
    <registro>
END.

/* FOR FIRST para usar o registro após sua execução */
FOR FIRST <tabela> NO_LOCK. END.
<registro>

FIND LAST/ FOR LAST: Mesma lógica do FIRST porém pegando o ultimo registro.

Melhorar desempenho na busca de registros em tabelas complexas

Para ter melhor desempenho ao buscar registros em tabelas com grande volume de registros procure nomear o índice que é melhor aplicado e use FIELDS para pegar apenas os campos que realmente serão usados, isso terá grande efeito no desempenho da busca:

FOR EACH <tabela> FIELDS (campo1, campo2, campo3) USE-INDEX <index>
WHERE <condição>
NO-LOCK:
    <lógica>
END.

Esse é só um rascunho de programa, mais detalhes podem ser consultados nos links a baixo:

https://help.consultingwerkcloud.com/openedge/102b/langref-07-09.html

https://stackoverflow.com/questions/42543675/openedge-record-lock-debugging

https://knowledgebase.progress.com/articles/Article/000045865

Deixe um comentário

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *

Esse site utiliza o Akismet para reduzir spam. Aprenda como seus dados de comentários são processados.