Concurrency 正在进行的并发操作4GL

Concurrency 正在进行的并发操作4GL,concurrency,openedge,progress-db,4gl,Concurrency,Openedge,Progress Db,4gl,问题描述: 有20个用户同时使用扫描,首先查找输入数据,如果未找到,则在数据库中创建一条记录。问题是,同时操作会出现死锁。 我尝试在找到记录时不锁定不等待,创建记录时操作将出现死锁 谢谢您的回答。您不幸地违反了ABL的基本“gotcha”-记录锁定将默认为SHARE-LOCK,即使您另行指定,这可能不是您想要的 基本规则是,如果您的事务范围小于记录范围,则当您离开事务时,记录将返回到共享锁。但我建议您阅读ABL指南中的相关章节 有很多方法可以解决这个问题。RELEASE关键字是一个。但我倾向于支

问题描述: 有20个用户同时使用扫描,首先查找输入数据,如果未找到,则在数据库中创建一条记录。问题是,同时操作会出现死锁。 我尝试在找到记录时不锁定不等待,创建记录时操作将出现死锁


谢谢您的回答。

您不幸地违反了ABL的基本“gotcha”-记录锁定将默认为SHARE-LOCK,即使您另行指定,这可能不是您想要的

基本规则是,如果您的事务范围小于记录范围,则当您离开事务时,记录将返回到共享锁。但我建议您阅读ABL指南中的相关章节

有很多方法可以解决这个问题。RELEASE关键字是一个。但我倾向于支持这样的想法,即应该使用单独的缓冲区来实际锁定记录。这样,您就可以让其他程序员非常清楚地了解情况

例如:

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.
这样,如果另一个程序员在您的事务块之外使用b-inscan3,程序将无法编译,而不是开始返回到SHARE-LOCK


请记住,您可以检查“锁定”和“可用”,但如果记录被锁定,则该记录不可用。

我认为您应该使用“独占锁定”而不是“无锁定”,以避免死锁。然后,您可以使用锁定功能检查记录是否被锁定,并执行相应的操作。
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 */