【问题标题】:Concurrency Operation in Progress 4GL进行中的并发操作 4GL
【发布时间】:2014-12-17 02:28:31
【问题描述】:
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.

问题描述: 有20个用户同时使用扫描,首先查找输入数据,如果没有找到,则在数据库中创建一条记录。问题是,同时运行会出现死锁。 我在查找时尝试NO-LOCK NO-WAIT与记录,创建记录时操作会出现死锁。

感谢任何回答。

【问题讨论】:

  • 我认为你应该使用 EXCLUSIVE-LOCK 而不是 NO-LOCK 来避免死锁。然后,您可以使用LOCKED函数来检查记录是否被锁定并进行相应的操作。

标签: concurrency openedge progress-db 4gl


【解决方案1】:

不幸的是,您违反了 ABL 的基本“陷阱”——即使您另有指定,记录锁定也会默认为 SHARE-LOCK,这可能不是您想要的。

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

有多种方法可以解决此问题。 RELEASE 关键字是一。但我倾向于认为您应该使用单独的缓冲区来实际锁定记录。这样你就可以让其他程序员非常清楚。

例如:

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 */

这样,如果另一个程序员在您的事务块之外使用 b-inscan3,程序将无法编译而不是开始退回到 SHARE-LOCK。

请记住,您可以检查 LOCKED 以及 AVAILABLE,但如果记录被锁定,则它不可用。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-02
    • 2022-01-10
    • 2020-12-25
    • 1970-01-01
    • 2012-09-24
    • 1970-01-01
    相关资源
    最近更新 更多