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记录,操作将在创建记录时显示死锁。
感谢任何答案。
答案 0 :(得分:0)
不幸的是,你已经违反了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,但如果记录被锁定,则该记录不可用。