Acesso ao mesmo registro no banco

Discussão em 'Progress 4GL' iniciado por antenor, Fevereiro 8, 2011.

  1. antenor

    antenor Membro Participativo

    Bom dia,

    Estou tendo o seguinte problema. Tenho uma rotina que faz um onde montei uma consulta em cWhere. Existem dois programas que fazem isto, entretanto quando algum usuário está acessando um código, mesmo que a consulta seja diferente e outro usuário estiver com o outro programa aberto ocorre alteração simultânea, ou seja, os registros são alterados aleatoriamente. Como o progress trata isto com exclusive-lock. Será que tenho que carregar um temp-table diferente e depois gravar no banco? Isto resolveria meu acesso concorrente?

    Desculpem pelo incômodo.

    Muito obrigado

    Sei que fica meio difícil de entender mas o código da gravação esta aqui:

    WHEN "gravar" THEN DO:
    ASSIGN icont2 = 0.
    FIND LAST Temp1 EXCLUSIVE-LOCK NO-ERROR.
    IF AVAIL Temp1 THEN ASSIGN icont2 = Temp1.nr.
    FIND FIRST Temp1 WHERE Temp1.nr = 1 NO-ERROR.
    IF AVAIL Temp1 THEN DO:
    ASSIGN dSaldo = 0
    dPedido = 0.
    REPEAT i = 1 TO icont2:
    if get-value("escolhe" + string(i)) = "on" then DO:
    FIND FIRST Temp1 WHERE Temp1.nr = i NO-ERROR.
    ASSIGN dSaldo = dSaldo + Temp1.Temp_pedido_valor.
    ASSIGN itot = itot + 1 .
    FIND FIRST Pedido WHERE Temp1.Ped_seq = Pedido.Ped_seq NO-ERROR.
    ASSIGN dPedido = dPedido + Pedido.Ped_valor.
    END.
    END.
    END.
    /* calcula qto tem de dinheiro para pagar */
    FIND LAST Temp1 EXCLUSIVE-LOCK NO-ERROR.
    FIND FIRST Pedido WHERE Pedido.Ped_seq = Temp1.Ped_seq NO-ERROR.
    IF AVAIL Pedido THEN do:
    /*Calcula o valor da receita*/
    FOR EACH saque WHERE saque.Cat_cat = Pedido.Cat_cat
    AND saque.Fon_cod = Pedido.Fon_cod
    AND saque.Vinc_Cod = integer(GET-VALUE("vinc")) NO-LOCK.

    ASSIGN dSaque = dSaque + Saque.Saq_valor.
    END.
    FOR EACH Libsaque WHERE Libsaque.Cat_cat = Pedido.Cat_cat
    AND Libsaque.Fon_cod = Pedido.Fon_cod
    AND Libsaque.Vinc_Cod = integer(GET-VALUE("vinc")) .
    ASSIGN dLibera = dLibera + Libsaque.Lib_valor.
    END.
    ASSIGN dValor = dSaque - dLibera.
    ASSIGN Temp1.Temp_saldo_valor = dValor.
    END.
    IF dValor < dPedido THEN
    ASSIGN cMensagem = "Saldo insuficiente para a liberação dos pedidos marcados".
    ELSE DO:
    /*inserido para numerar*/
    FIND FIRST Numero NO-ERROR.
    IF GET-VALUE("pf") = "PF" THEN ASSIGN nrprimeiro = Numero.Num_PF_Aut.
    ELSE nrprimeiro = Numero.Num_NL_Aut.
    /*fim numerar*/
    REPEAT i = 1 TO icont2:
    IF get-value("escolhe" + string(i)) = "on" then DO: /*trata os campos marcados*/
    FIND FIRST Temp1 WHERE Temp1.nr = i NO-ERROR.

    /*aqui eu pego uma seleção anterior e uso a tabela temporária para gravar*/

    FIND FIRST Pedido WHERE Temp1.Ped_seq = Pedido.Ped_seq NO-ERROR.


    IF (dValor >= Pedido.Ped_valor) THEN DO: /*Libera enquanto tem saldo
    /* Guarda imagem do registro antes de proceder uma alteracao */
    {sisconum_guardaTempMult.i Pedido}
    /* Guarda Historico da Alteracao */
    run sisconum_savePedido.p (input table tt-Pedido).*/

    Create Historico_Pedido.
    ASSIGN Historico_Pedido.Cat_cat = Pedido.Cat_cat
    Historico_Pedido.Cat_ND = Pedido.Cat_ND
    Historico_Pedido.Fon_cod = Pedido.Fon_cod
    Historico_Pedido_OS_Cod = Pedido_OS_Cod
    Historico_Pedido.Ped_Ano = Pedido.Ped_Ano
    Historico_Pedido.Ped_data = Pedido.Ped_data
    Historico_Pedido.Ped_data_msg = Pedido.Ped_data_msg
    Historico_Pedido.Ped_flag_ped = Pedido.Ped_flag_ped
    Historico_Pedido.Ped_numped = Pedido.Ped_numped
    Historico_Pedido.Ped_OB = Pedido.Ped_OB
    Historico_Pedido.Ped_Obs = Pedido.Ped_Obs
    Historico_Pedido.Ped_Ob_NL = Pedido.Ped_Ob_NL
    Historico_Pedido.Ped_OP_Destaque = Pedido.Ped_OP_Destaque
    Historico_Pedido.Ped_seq = Pedido.Ped_seq
    Historico_Pedido.Ped_Usuario = Pedido.Ped_Usuario
    Historico_Pedido.Ped_valor = Pedido.Ped_valor
    Historico_Pedido.Proj_PI = Pedido.Proj_PI
    Historico_Pedido.Proj_projatv = Pedido.Proj_projatv
    Historico_Pedido.proj_ptres = Pedido.proj_ptres
    Historico_Pedido.Proj_uo = Pedido.Proj_uo
    Historico_Pedido.TipoMSG_cod = Pedido.TipoMSG_cod
    Historico_Pedido.UGR_Cod = Pedido.UGR_Cod
    Historico_Pedido.UG_codug = Pedido.UG_codug
    Historico_Pedido.UG_RM = Pedido.UG_RM
    Historico_Pedido.UO_Cod = Pedido.UO_Cod
    Historico_Pedido.Usu_CPF_Mod = Pedido.Usu_CPF_Mod
    Historico_Pedido.Usu_data_Mod = Pedido.Usu_data_Mod
    Historico_Pedido.Usu_Hora_Mod = Pedido.Usu_Hora_Mod
    Historico_Pedido.Vinc_Cod = Pedido.Vinc_Cod.
    Historico_Pedido.hist_data = STRING(TODAY) + " " + STRING(TIME, "HH:MM:SS").
    /*Libera Pedido*/
    ASSIGN Pedido.Ped_flag_ped = "L".
    ASSIGN Pedido.Ped_emissao = TODAY.
    ASSIGN Pedido.Vinc_Cod = ivinc.
    ASSIGN Pedido.Ped_lib = yes.
    ASSIGN Pedido.Ped_dat_lib = TODAY.
    ASSIGN Pedido.Usu_CPF_Mod = cCPF.
    ASSIGN Pedido.Usu_data_Mod = TODAY .
    ASSIGN Pedido.Usu_Hora_Mod = STRING(TIME,"HH:MM:SS").
    /*Numera Pedido*/
    FIND FIRST Numero NO-ERROR.
    IF GET-VALUE("pf") = "PF" THEN ASSIGN nr1 = Numero.Num_PF_Aut.
    ELSE nr1 = Numero.Num_NL_Aut.
    IF AVAILABLE Numero THEN DO:
    IF GET-VALUE("pf") = "PF" THEN DO:
    ASSIGN Pedido.Ped_OB = ano + "PF" + STRING(Numero.Num_PF_Aut,"999999").
    ASSIGN Numero.Num_PF_Aut = Numero.Num_PF_Aut + 1.
    END.
    ELSE DO:
    ASSIGN Pedido.Ped_OB = ano + "NL" + STRING(Numero.Num_NL_Aut,"999999").
    ASSIGN Numero.Num_NL_Aut = Numero.Num_NL_Aut + 1.
    ASSIGN Pedido.Ped_evento_sec = "560611".
    IF Pedido.Cat_cat = "A" THEN DO:
    IF Pedido.UG_codug = 164204 THEN
    ASSIGN Pedido.Ped_evento = "700714".
    ELSE
    ASSIGN Pedido.Ped_evento = "700703".
    END.
    IF Pedido.Cat_cat = "B" OR Pedido.Cat_cat = "C" THEN
    ASSIGN Pedido.Ped_evento = "700703".
    IF Pedido.Cat_cat = "E" THEN
    ASSIGN Pedido.Ped_evento = "700706".
    END.
    END.
    /*Atualiza Valores*/
    FIND FIRST Libsaque WHERE Libsaque.Cat_cat = Pedido.Cat_cat
    AND Libsaque.Fon_cod = Pedido.Fon_cod
    /* AND Libsaque.UO_Cod = Pedido.UO_Cod
    AND Libsaque.UGR_Cod = Pedido.UGR_Cod */
    AND Libsaque.Vinc_Cod = Pedido.Vinc_Cod NO-ERROR.
    IF AVAILABLE Libsaque THEN DO:
    ASSIGN Libsaque.Lib_valor = Libsaque.Lib_valor + Pedido.Ped_valor.
    Libsaque.Usu_CPF_Mod = cCPF.
    Libsaque.Usu_data_Mod = TODAY .
    Libsaque.Usu_Hora_Mod = STRING(TIME,"HH:MM:SS").
    END.
    ELSE DO:
    CREATE Libsaque.
    ASSIGN Libsaque.Cat_cat = Pedido.Cat_cat
    Libsaque.Fon_cod = Pedido.Fon_cod
    Libsaque.Vinc_Cod = Pedido.Vinc_Cod
    Libsaque.UO_Cod = Pedido.UO_Cod
    Libsaque.UGR_Cod = Pedido.UGR_Cod
    Libsaque.Lib_valor = Libsaque.Lib_valor + Pedido.Ped_valor
    Libsaque.Usu_CPF_Mod = cCPF
    Libsaque.Usu_data_Mod = TODAY
    Libsaque.Usu_Hora_Mod = STRING(TIME,"HH:MM:SS").
    END.
    ASSIGN dValor = dValor - Pedido.Ped_valor.
    END. /*Tem saldo*/
    END. /*Campo marcado*/
    END. /*REPEAT*/
    FIND LAST Numero NO-ERROR.
    IF GET-VALUE("pf") = "PF" THEN ASSIGN nr2 = Numero.Num_PF_Aut - 1.
    ELSE nr2 = Numero.Num_NL_Aut - 1.
    FIND CURRENT Pedido NO-LOCK NO-ERROR.
    ASSIGN cMensagem = "Foram processadas, Primeiro = " + STRING(nrprimeiro) + " Último = " + STRING(nr2) .
    END.
    END. /* WHEN */
  2. muertebr

    muertebr Membro Participativo

    Algumas dicas.

    Inves de fica usando varios assign, usa tudo no mesmo assign:

    Código:
    assign campo1 = 222.
    assign campo2 = 3333.
    Código:
    assign campo1 = 222
              campo2 = 3333.
    ao inves de ficar usando varios exclusive-lock, você pode usar buffer com rowid.

    segue código que faz parte de uma trigger (movto_tit_acr)
    Código:
    FIND FIRST spawTitulos NO-LOCK
        WHERE spawTitulos.tituloId  = tit_acr.cod_tit_acr     AND
              spawTitulos.clienteId = tit_acr.cdn_cliente     AND
              spawTitulos.parcela   = tit_acr.cod_parcela     AND
              spawTitulos.especie   = tit_acr.cod_espec_docto AND
              spawTitulos.serie     = tit_acr.cod_ser_docto NO-ERROR.
    IF NOT AVAIL spawTitulos THEN DO:
        CREATE spawTitulos.
        ASSIGN spawTitulos.tituloId       = tit_acr.cod_tit_acr
               spawTitulos.clienteId      = tit_acr.cdn_cliente
               spawTitulos.parcela        = tit_acr.cod_parcela
               spawTitulos.especie        = tit_acr.cod_espec_docto
               spawTitulos.serie          = tit_acr.cod_ser_docto
               spawTitulos.natureza       = (IF espec_docto.ind_tip_espec_docto = "normal" THEN "DE" ELSE "CR")
               spawTitulos.ativo          = YES.
    END.
    FIND FIRST bfspawTitulos EXCLUSIVE-LOCK
        WHERE ROWID(bfspawTitulos) = ROWID(spawTitulos).
    ASSIGN spawTitulos.valor          = a-vencer
           spawTitulos.dataEmissao    = tit_acr.dat_emis_docto
           spawTitulos.dataVencimento = tit_acr.dat_vencto_tit_acr
           spawTitulos.saldo          = tit_acr.val_sdo_tit_
    
    Caso não va usar a tabela, use no-lock pois se não a tabela fica em shared-lock, onde não é bom e tambem após ter usado a tabela pode ser usado release.

    Código:
    find first tabela exclusive-lock
    assign tabela.campo1 = 2222.
    release tabela.
    Segue ainda em anexo um Manual de Performace para o progress.

    Arquivos Anexados:

  3. antenor

    antenor Membro Participativo

    Valeu pelas dicas e obrigado pelo manual.

Compartilhe esta Página