进度OpenEdge如何防止有人更新记录

时间:2016-03-29 08:38:36

标签: updating progress-4gl openedge

我需要另一种方法来阻止某人访问特定的代码。

我将解释这个场景。

有两个程序。

在第一个程序中,最终用户创建形式发票。然后他/她查看发票上的详细信息。代码以EXCLUSIVE-LOCK中的主表记录显示详细信息。这是为了防止其他最终用户在第一个用户忙于查看详细信息时更改任何内容。即使形式发票已完成且无法再更改。主表的记录仍然是EXCLUSIVE-LOCK。这是错误的,但它阻止其他用户在第一个用户仍在忙于更新它时搞乱它。但是,在此程序中工作的人员将程序保留在详细视图中。他们不会出去。

问题是当第二个程序用于在形式发票上发送项目时。它使用相同的主表记录。因此,无法做任何事情,因为第一个程序仍然在EXCLUSIVE-LOCK中。

我的问题是......

如何防止用户在第一个程序中更改数据,就好像主表的记录处于EXCLUSIVE-LOCK状态,但实际上没有将其置于独占锁中?多次会议......

3 个答案:

答案 0 :(得分:2)

这可能是更好的评论,但我没有足够的声誉点来发表评论。遗憾。

一些注意事项:

  1. 乐观锁定 - 如果它适合您的情况 - 几乎可以肯定是最佳解决方案。

  2. 如果您要向表中添加isLocked字段,您可能需要其他几个字段:

    • 记录被锁定的日期/时间 - 或者是到期时间戳
    • LockHolder - 所以你知道你是否得到它。
  3. 过期可以是自动的(与cron扫描一样),也可以忽略,除非其他人想要记录。设置锁定的程序也必须足够智能,以检查它是否仍然保持它。它变得复杂了。

  4. 有时候对表进行架构更改不方便,或者有太多表需要更改。在这些情况下,您可以将这些字段添加到单独的LockIt表中。一个表可以处理所有其他表的这些锁。

  5. 除了:
    我们还将LockIt表用于其他目的:确保一次只能运行给定程序的一个副本。 (通常这适用于cron作业或批处理守护程序。)程序对LockIt表中的特定记录进行独占锁定(但不启动事务!),只要程序正在运行,它就会保留该锁定。

答案 1 :(得分:0)

最有可能的是,您的交易范围是错误的。我会继续并假设您正在尝试发票仍然打开发票计划。然后你不能,因为记录仍然被锁定。有可能你的整个程序都是一个交易,只要屏幕正在运行,记录就会保持锁定状态。尝试并重新访问您的更新,将实际更新操作包含在DO TRANSACTION块中,将一些MESSAGE TRANSACTION语句放在不同的位置并查看结果。这将帮助您找到导致“相信”记录仍然需要锁定的点。

答案 2 :(得分:-1)

我假设你没有使用appserver,因为在这种情况下,这种行为很可能不会成为问题。

一种解决方案可能是改变为乐观锁定"做法。这意味着你开始使用" NO-LOCK"一旦你需要更改记录,你就可以将锁升级为EXCLUSIVE-LOCK。这种方法可行,但您需要确保记录仍然存在且未被其他用户更改。

根据您的发票实际更改的频率,这可能(或可能不是)成为解决方案。如果发生事故"偶尔发生#34;这可能是一个可行的解决方案。如果它经常(每天左右)发生,你需要做其他事情。

乐观方法的基本伪代码:

FIND FIRST record WHERE somethingsomething NO-LOCK.

/* Here goes code for displaying the record */
/* .... */

/* Here's the updates */
IF userWantsToSave THEN DO:
    FIND CURRENT record EXCLUSIVE-LOCK NO-ERROR NO-WAIT.
    IF AVAILABLE record THEN DO:
        IF CURRENT-CHANGED record THEN DO:
            MESSAGE "Changed!" VIEW-AS ALERT-BOX ERROR.
            /* Your code goes here */
        END.
        ELSE DO:
            /* Your code for updating goes here */

            MESSAGE "Success!" VIEW-AS ALERT-BOX INFORMATION.
        END.
    END.    
    ELSE IF NOT AVAILABLE record THEN DO:
        IF LOCKED record THEN DO:
            MESSAGE "Locked!" VIEW-AS ALERT-BOX ERROR.
            /* Your code goes here */
        END.
        ELSE DO:
            MESSAGE "Deleted!" VIEW-AS ALERT-BOX ERROR.
            /* Your code goes here */
        END.
    END. 
END.

Here's an example from the knowledgebase that goes more into depth with this.