Concurrency Operation in Progress 4GL

406 views Asked by At
REPEAT With FRAME:

  prompt-for IN-SCAN3.scan.
  if input IN-SCAN3.scan="" then Do:
    Message "please input date.". 
    undo,retry.
  end.
  else DO:
    FIND FIRST in-scan3 USING IN-SCAN3.scan NO-LOCK NO-WAIT NO-ERROR.
    if avail In-scan3 then DO:
        str="OK".
        display str.
        next-prompt IN-SCAN3.scan. 
    end.
    else DO:    
        CREATE In-scan3.
        ASSIGN IN-scan3.scan=INPUT in-scan3.scan.

        str="NO". DISPLAY str.
        next-prompt In-scan3.scan.
    END.
  end.
  begin=begin + 1.
end.

Question desc: There are 20 users using scanning at the same time,first find input data, if not found, then create one record in the database. The question is, at the same time operating will appear dead lock. I try NO-LOCK NO-WAIT with record when find,operating will appear dead lock when create a record.

thanks any answer.

1

There are 1 answers

0
Andy Jones On

You have unfortunately fallen foul of ABL's basic "gotcha" -- record locking will default to SHARE-LOCK even if you specify otherwise, and this is probably not what you want.

The basic rule is that if your transaction scope is smaller than your record scope then the record will drop back to a SHARE-LOCK when you leave the transaction. But I recommend you read the relevant chapter in the ABL guide.

There are a number of ways to fix this. The RELEASE keyword is one. But I tend to favour the idea that you should use a separate buffer for actually locking the record. That way you make things very clear to other programmers.

For example:

def buffer b-in-scan3 for in-scan3.

repeat:
    prompt-for in-scan3.scan.

    /*** etc. ***/

    else
    do for b-in-scan3 transaction:
        find first b-in-scan3 using in-scan3.scan
            exclusive no-wait no-error.

        if  not avail b-in-scan3
        and not locked b-in-scan3
        then
        do:
            create b-in-scan3.
            b-in-scan3.scan = input in-scan3.scan.
        end.

     end.  /* of transaction */

 end. /* of repeat */

This way if another programmer uses b-inscan3 outside of your transaction block, the program will fail to compile rather than start dropping back to SHARE-LOCK.

Remember that you can check LOCKED as well as AVAILABLE, but if a record is locked then it's not available.