Exclusive-lock

310 views
Skip to first unread message

Pierre blitzkow

unread,
Feb 12, 2009, 4:22:30 PM2/12/09
to Progre...@googlegroups.com, Progress Yahoo
Boa Tarde Pessoal,

Normalmente quando utilizamos o exclusive-lock juntamente com um find first se o registro esta bloqueado aparece a tela padrão do progress avisando que o registro esta em uso por outro usuário com um botão de cancelar, caso o usuário aperte em cancelar o programa pula o find e continua porém gostaria de saber como fazer para avisar que o registro esta bloqueado e não permitir que o usuário clique em cancelar e obrigue fazer esperar até desbloquear o registro ?

Grato,


-------
Pierre Blitzkow

Vanildo Prates

unread,
Feb 12, 2009, 4:27:40 PM2/12/09
to Progre...@googlegroups.com
Ola Pierre,

Creio que impedir o usuario de clicar em cancelar ou desabilitar o botão não é possivel, mas vc pode validar se o registro esta bloqueado ou não, daí poderia dar um pause ou emitir um alerta sei la.

Não estou achando o comando que verifica se o registro esta bloqueado, mas sei que tem.

att



2009/2/12 Pierre blitzkow <pie...@blitzkow.com>



--

Matheus Antonelli

unread,
Feb 12, 2009, 4:33:45 PM2/12/09
to Progre...@googlegroups.com
Boa noite:

Usa-se a função LOCKED() para isso:

FIND customer USING customer.cust-num NO-ERROR NO-WAIT. 

IF NOT AVAILABLE customer THEN DO: 

    IF LOCKED customer THEN MESSAGE "Customer record is locked".
    ELSE MESSAGE "Customer record was not found". 

END.

Abraços,
Matheus.
Fórum Progress



2009/2/12 Vanildo Prates <vpr...@gmail.com>

Wanderley S

unread,
Feb 12, 2009, 4:34:50 PM2/12/09
to Progre...@googlegroups.com
Pierre,
 
Use o FIND com a cláusula NO-WAIT e em seguida utilize a função LOCKED para testar se o registro está bloqueado.
 
Dessa forma, o progress não ficará aguardando o registro ser liberado, não exibirá a mensagem de registro bloqueado e você pode testar o bloqueio com a função LOCKED (if locked tabçe)..
 
Você pode inclusive utilizar um loop para aguardar, mas cuidado para não causar um loop infinito.
 
Sds,
 
Wanderley.

2009/2/12 Vanildo Prates <vpr...@gmail.com>



--
Abraço,

Wanderley.

"Nada baixa mais o nível da conversa do que elevar a voz".  Stanley Horowitz

"...aos loucos a sua impressão de bem-estar os leva à perdição." Pv 1.32b.

"Denunciei a fome como um flagelo fabricado pelos homens, contra outros homens".
Josué de Castro

Pierre blitzkow

unread,
Feb 13, 2009, 5:40:48 AM2/13/09
to Progre...@googlegroups.com
Bom Dia Pessoal,

Agradeço a ajuda de todos, com base na dica de todos desenvolvi o seguinte trecho de código responsável por baixar a quantidade de um registro, estou anexando abaixo para todos analisarem e dar uma opinião se ainda pode estar sussetivel a algum erro e não baixar esta quantidade:

procedure pi-baixa-quant:

FOR EACH scb-op-it WHERE scb-op-it.num-op = INPUT FRAME fr-op fl-num-op
                       AND   scb-op-it.dt-op  = vd-dt-op
                       NO-LOCK:

        FIND FIRST scb-mov-atual WHERE scb-mov-atual.it-codigo = scb-op-it.it-codigo
                                 AND   scb-mov-atual.endereco  = scb-op-it.endereco
                                 NO-ERROR NO-WAIT
        IF NOT AVAILABLE scb-mov-atual THEN DO:
            IF LOCKED scb-mov-atual THEN DO:
                MESSAGE 'Registro de quantidade da bobina esta bloqueado, Ordem de Operação não pode ser salva.' SKIP
                        'Tente novamente.'
                    VIEW-AS ALERT-BOX INFO BUTTONS OK.
                RETURN 'NOK'.
            END.
            ELSE DO:
                MESSAGE 'Registro de quantidade de bobina não foi encontrado.'
                    VIEW-AS ALERT-BOX INFO BUTTONS OK.
                RETURN 'NOK'
            END.
        END.
        ELSE DO:           

            ASSIGN scb-mov-atual.quant = scb-mov-atual.quant - (scb-op-it.quant-ped
                                                             +  (scb-op-it.quant-rolo * 100)
                                                             +  scb-op-it.quant-sucata
                                                             +  scb-op-it.quant-ret)
                   scb-mov-atual.lance = vi-lance.

            RELEASE scb-mov-atual   NO-ERROR.

            RETURN 'OK'.

        END.
    END.
end procedure.

Muito obrigado.

Pierre.

2009/2/12 Wanderley S <wand...@gmail.com>



--
Pierre Blitzkow

MARCOS BATISTA

unread,
Feb 13, 2009, 5:57:25 AM2/13/09
to pie...@blitzkow.com, Progre...@googlegroups.com
Apenas mais uma dica: sempre use Fields no for each (veja abaixo o exemplo)

FOR EACH scb-op-it FIELDS(num-op /* INDICAR campos de que você usará na seqüência do programa*/)
WHERE scb-op-it.num-op = INPUT FRAME fr-op fl-num-op
AND scb-op-it.dt-op = vd-dt-op
NO-LOCK:
:::
Outra coisa, sempre que possível use o USE-INDEX, indicando o melhor índice para a combinação da cláusula de where.

Isto impacta em performance, que para mim, depois da funcionalidade, é o critério mais importante da programação para banco de dados relacionais.

Agora, aidna quanto à funcionalidade, adotamos o critério de que rotinas que atualizam banco de dados, SEMPRE usar o DO TRANSACTION, e mais: em cada FOR EACH dentro deste DO TRANSACTION use o "ON ERROR UNDO, RETURN...".
Isto é fundamental para você evitar transações "quebradas" ou "sujas", aliás, este é o pior erro que pode ocorrer em programação, gerando os erros de cálculos e atualizações mais difíceis de se encontrar.

Veja baixo um exemplo de programa usando este critério:
Gravar: DO TRANSACTION
ON ERROR UNDO Gravar, RETURN ERROR
ON QUIT UNDO Gravar, RETURN ERROR
ON ENDKEY UNDO Gravar, RETURN ERROR
ON STOP UNDO Gravar, RETURN ERROR:
Estoq: FOR EACH tt_estoq ON ERROR UNDO Gravar, RETURN ERROR:
IF tt_estoq.lfechado THEN DO:
MESSAGE "Estoque já fechado. Programa:" PROGRAM-NAME(1).
UNDO Gravar, RETURN ERROR.
END.
ASSIGN tt_estoq.lfechado = YES.
END
END. /* Gravar */

---------------


Batista
Analista de Sistemas - Depto.Informática
Cooperativa Agrária Agroindustrial
Fone: (42) 3625-8108
bat...@agraria.com.br
Visite: www.agraria.com.br

>>> pie...@blitzkow.com 13/02/2009 08:40:48 >>>

Wanderley S

unread,
Feb 13, 2009, 6:55:46 AM2/13/09
to Progre...@googlegroups.com
Concordo plenamente com o Marcos Batista com relação à preocupação com a performance, cláusula Fields, etc. Tem que ter essa preocupação mesmo.
 
Só tenha cuidado com o uso do Transaction no seguinte caso: se houver uma quantidade muito grande de registros tratados dentro do transaction, você pode ter problemas de performance. Nesse caso o ideal é reduzir o escopo da transação.
 
Com relação ao use-index, concordo em parte. Cada um tem uma forma de trabalhar. O que eu faço é tentar ao máximo é adaptar as cláusulas WHERE a um índice existente na tabela.  Dessa forma o próprio progress já escolhe o "melhor" índice. Eu sempre compilo os programas usando XREF e vejo no arquivo xref gerado, se encontro a tag WHOLE-INDEX, que significa que o programa está lendo a tabela inteira, sem uso de nenhum índice. (Exceção para as tabelas que possuem um único registro, sempre indica whole-index - ex.: tabelas de parâmetros). Outra sugestão é estudar a fundo como o progress trata índices. Existe bom material na internet sobre isso, geralmente em inglês.
 
Abraços,
 
Wander.

2009/2/13 MARCOS BATISTA <BAT...@agraria.com.br>

Pierre blitzkow

unread,
Feb 13, 2009, 12:44:09 PM2/13/09
to Progre...@googlegroups.com
Mais uma vez muito obrigado pela colaboração de todos, principalmente pela aprofundada no assunto pelo Marcos Batista e Wanderley, aproveitando para tirar mais uma dúvida, quando abro uma procedure o progress já não  trata esta procedure como uma transaction.

Grato.

2009/2/13 Wanderley S <wand...@gmail.com>



--
Pierre Blitzkow

Wanderley S

unread,
Feb 13, 2009, 1:04:47 PM2/13/09
to Progre...@googlegroups.com
Pierre,
 
Para saber se é transação, você pode utilizar a função TRANSACTION, que retorna yes/no.
 
De modo "simplório", uma procedure só será transação se ela tiver dentro de uma transação já iniciada -  Ex: executada de dentro de um for each exclusive-lock, com atualização de dados - ou se dentro ela possuir um for each com essas mesmas características.
 
Mas, por via das dúvidas, use a função TRANSACTION que te dirá exatamente se está ocorrendo uma transação ou não.
 
Sds,
 
Wanderley.

2009/2/13 Pierre blitzkow <pie...@blitzkow.com>

leonardo vieira

unread,
Feb 13, 2009, 1:49:51 PM2/13/09
to Progre...@googlegroups.com
Eu gostaria de saber se muda muito a sitaxe do progress quando se usa o banco Oracle.

2009/2/13 Wanderley S <wand...@gmail.com>



--
Leonardo Vieira de Lima
Téc. em informática
tel: 051 81486532
           33074147
leona...@gmail.com
Reply all
Reply to author
Forward
0 new messages