我意识到Progress ABL有这样做的自然倾向: 默认情况下,Progress显示消息:正在使用中 上 。等待或选择CANCEL停止。 (2624) 这条2624消息提供了……
我假设你已经熟悉find ... exclusive-lock / share-lock no-wait no-error,因为你不能使用lock-function而不使用no-wait。
查询_lock可能没有那么糟糕,因为评论使它听起来很糟糕。您只会在用户遇到锁定冲突时偶尔执行此操作。此外,性能在很大程度上取决于当前锁定的条目总数。
重要的是以正确的方式查询_lock,具体取决于Progress版本。
重复 我对类似问题的回答 :
在11.4之前的版本中,字段未编入索引,但所有使用的锁都在表的开头,因此您可以使用
FOR EACH _Lock NO-LOCK: IF _Lock._Lock-Usr = ? THEN LEAVE.
(_Lock._Lock-Name =?也没关系)。看到 http://knowledgebase.progress.com/articles/Article/P161995 (显然,对于非常大的锁定表或许多锁定,这在实践中并非如此。由于扫描整个锁定表确实需要一些时间,所以这可能是你能做的最好的。)
在11.4和11.5中,填充的条目不再在开头,因此旧代码将给出错误的结果(请参阅 http://knowledgebase.progress.com/articles/Article/000056304 ,这在11.5.1)中得到修复。幸运的是,扫描锁表现在要快得多,所以你可以使用
FOR EACH _Lock NO-LOCK WHERE _Lock-Recid <> ?:
在同一篇文章中提到。从技术上讲,这不是通过索引实现的。 (索引不适用于&lt;&gt;运算符。)
我很同情为用户提供关于谁持有锁的好消息的愿望。但是kbase并不是在开玩笑。以这种方式使用_LOCK是一个非常糟糕的主意。
11.4+使它变得不那么糟糕,但在大型生产系统上做这件事仍然是一件非常痛苦的事情。
在具有默认锁定表大小(-L 8192)的小型系统上,它似乎是“正常”。在具有大型锁定表的大型活动系统上(值为-L北以下的值很常见)并且使用了大量锁定,您将获得非常非常不同且非常消极的体验。
更好的解决方案可能是查看“被阻止的用户”:
for each dictdb._Connect no-lock where _Connect-usr <> ? and _Connect-wait <> " -- ": /* there are spaces around the '--' */ display _Connect. end.
这将更快,并可能告诉您需要知道的一切。
如果你打算扫描_LOCK,无论kbase的警告是什么,至少在你的循环中放置一些逻辑来跟踪它需要多长时间并且如果它太长就会挽救。这样的事情可能是一个好的开始:
etime( yes ). for each dictdb._Lock where _Lock._Lock-usr <> ? and _Lock._Lock-recid <> ?: if etime > 500 then leave. /* whatever ... */ end.