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

Leitura de Registros: Opções de LOCK

Discussão em 'Progress 4GL' iniciado por FernandaSantos, Janeiro 26, 2009.

  1. FernandaSantos

    FernandaSantos Membro Participativo

    Olá Pessoal, venho postar uma dica tem grande utilidade quanto a melhora de performance do código:
    Quanto aos modos de Leitura de registros no Progress podemos assim definir:

    Shared-Lock: O registro fica livre até que haja uma alteração na tabela, neste caso o Progress passa o registro para bloqueado. Outros usuários podem ler o registro com shared-lock e no-lock
    No-Lock: Outros usuários podem ler o registro com qualquer bloqueio. Somente leitura, não bloqueia o registro.
    Exclusive-Lock: Bloqueia o registro com o usuário corrente. Ninguém altera o registro até que encerre o processo.

    A opção de LOCK default do progress é o Shared-Lock :
    Quando dois usuários tentam alterar o mesmo registro acessando a mesma tabela com SHRED-LOCK um bloqueia o outro causando o chamado DEAD-LOCK. Ambos querem atualizar a tabela e estão esperando que o Progress atualize de SHARED-LOCK para EXCLUSIVE-LOCK (mas essa atualização não ocorre). Sendo assim, é necessário que um deles cancele a alteração.

    Abb,

    Fernanda
  2. pedro_lemes

    pedro_lemes Membro Participativo

    Ola,

    Apenas complementando:

    Por isso existe a necessidade no progress de utilizarmos blocos transacionais inteligentes e menores para reduzirmos o tempo de lock dos registros e a eficiencia na utilizacao do banco.

    exemplo de transacao grande (errado):

    Código:
    /*inicio transacao*/
    for each tabela1: /*tabela em share-lock*/
    
       assign campo1 = "1" 
                 campo2 = "2". /*nesse ponto, o registro assume o exclusive-lock e so o retornara apos termino do 
                                          FOR EACH todo*/
    
       find first tabela2 where tabela2.campo1 = tabela1.campo1 no-lock no-error.
       if avail(tabela2) then
           campo3 = tabela2.campo3.
    end.
    /*fim transacao*/
    
    No caso acima, prendemos a transacao no FOR EACH, o que vai ocasionar num numero grande de registros presos e problemas de lock.

    O ideal seria:

    Código:
    define buffer bftabela1 for tabela1. /*criacao de um buffer*/
    for each bftabela1 no-lock: /*tabela em no-lock, nao trava registro*/
       if can-find(tabela2 where tabela2.campo1 = tabela1.campo1 no-lock) then do transaction: /*inicio da transacao*/
           find first tabela2 where tabela2.campo1 = tabela1.campo1 no-lock no-error.
           find first tabela1 where tabela1.campoprincipal = bftabela1.campoprincipal exclusive-lock no-error.
           assign campo1 = "1"
                     campo2 = "2" 
                     campo3 = tabela2.campo3.
           find current tabela2 no-lock no-error.
       end. /*fim transacao*/
    end.
    
    Da forma acima, dentro de cada passo do for each, travamos o registro apenas se encontrarmos o que precisamos no can-find e ja destravamos em seguida, pra darmos o proximo passo no for each.

    Abraço.
  3. fasouza

    fasouza Membro Participativo

    No exemplo acima podemos usar para destravar o registro:

    Código:
    release tabela2.
    no lugar de:

    Código:
    find current tabela2 no-lock no-error.

Compartilhe esta Página