[RESOLVIDO] Como evitar o lock de registro?

Discussão em 'EMS , HCM e Totvs 11' iniciado por denismaster, Fevereiro 16, 2016.

Status do Tópico:
Não esta aberto para novas mensagens.
  1. denismaster

    denismaster Membro Participativo

    E aew pessoal, blza?

    [HISTÓRIA]
    Fiz um programa de apontamento que é 99% em cima do meu bd específico,
    E quando o usuário faz o apontamento o programa só troca o estado da ordem de produção para iniciada.

    [PROBLEMA]
    Mas devido a isso meu programa bloqueia muita gente dando a mensagem de "ord-prod em uso por ..."
    E o programa fica aberto em 5 computadores o dia todo.

    [DÚVIDA]
    Como fazer para evitar esses locks e mesmo assim gravar a informação?

    Obrigado.
  2. rafael.andrade

    rafael.andrade Membro Master Moderador Equipe de Suporte

    Por padrão, em todos FOR EACH e FIND, usar o comando NO-LOCK, exemplo:

    FIND FIRST tabela WHERE tabela.id = 15 NO-LOCK NO-ERROR.

    E quando efetivamente for alterar o registro, usar o EXCLUSIVE-LOCK.

    A parte onde fica a alteração, sempre colocar dentro de uma DO TRANS para que o resto do código não fique travado.

    Se realmente precisar de mensagens no meio do processo, então crie uma tabela temporária para armazenar as mensagens e exibir somente depois da transação.

    Exemplo:
    ===============================================================
    DEF TEMP-TABLE ttMsg NO-UNDO
    FIELD cod AS INTEGER
    FIELD msg AS INTEGER

    [CÓDIGO INICIAL, TUDO COM NO-LOCK]

    MESSAGE "Transação Ativa?" SKIP "R.: " + STRING(TRANS,"SIM/NAO")
    VIEW-AS ALERT-BOX INFO BUTTONS OK.

    TMaior:
    DO TRANS:
    [CÓDIGO ALTERANDO]
    IF CONDICAO = TRUE THEN DO:
    RUN CriaMsg(100,"Erro, OP XXXX não foi encontrada!").
    UNDO TMaior, LEAVE.
    END.
    END.

    RUN ExibirMensagens.
    ===============================================================

    1. A Procedure CriaMsg cria um registro na temp-table ttMsg NO-UNDO (não some se desfazer a transação).

    2. A Procedure ExibirMensagens faz um FOR EACH na ttMsg mostrando as mensagens armazenadas.

    3. Dessa forma, como não exibe a mensagem dentro da transação, não vai ficar travando os registros.

    4. Como colocamos todo o código que altera dentro de uma transação, a procedure inteira não se torna uma transação.
    Se não colocasse o DO TRANS, ao fazer a alteração de algum registro ou EXCLUSIVE-LOCK, na mensagem "Transação ativa" já apareceria SIM
    Mas como colocamos, a transação fica amarrada somente naquele bloco.

    5. Toda vez que fizer uma alteração usando FIND, logo em seguida faça o NO-LOCK desse registro, exemplo:
    FIND FIRST tabela WHERE [CONDICAO] EXCLUSIVE-LOCK NO-ERROR.
    ASSIGN tabela.campo = "Alterando".
    FIND CURRENT tabela NO-LOCK NO-ERROR.


    Se tiver mais ideias eu colocarei aqui depois.

    Abraço

    Rafael
    Rsacoman curtiu isso.
  3. bootstrapmaster

    bootstrapmaster Moderator Moderador Equipe de Suporte

    depois da aula do nosso amigo Rafael só indico usar o comando release ord-prod depois de tudo feito pra que o progress largue de vez o registro.
    rafael.andrade curtiu isso.
  4. rafael.andrade

    rafael.andrade Membro Master Moderador Equipe de Suporte

    Esse "RELEASE ord-prod" não conhecia, pensava que o "RELEASE" era somente para limpar da memória variáveis HANDLE e COM-HANDLE.

    Legal!!!
  5. denismaster

    denismaster Membro Participativo

    Muito obrigado Rafael e bootstrapmaster.
    Nunca tinha visto "DO TRANS:"
    Resolveu o problema na hora.

    Obrigado mesmo!
    :)
  6. bootstrapmaster

    bootstrapmaster Moderator Moderador Equipe de Suporte

    Só toma cuidado com o do transaction, porque se vc processar 300 registros dentro de um bloco desses, e no ultimo registro dá um erro, que gere um undo, leave, o progress vai desfazer tudo, vai desfazer os 300 registros processados.
Status do Tópico:
Não esta aberto para novas mensagens.

Compartilhe esta Página