2016-03-29 79 views
0

我需要一種替代方法來防止某人訪問特定的一段代碼。Progress OpenEdge如何防止某人更新記錄

我會解釋一下這個場景。

有兩個程序。

在第一個程序中,最終用戶創建了形式發票。然後他/她查看發票上的詳細信息。代碼在EXCLUSIVE-LOCK中顯示主表記錄的詳細信息。這是爲了防止其他最終用戶在第一個用戶忙於查看詳細信息時進行更改。所以即使形式發票已經完成並且不能再改變。主表的記錄仍然在EXCLUSIVE-LOCK中。這是錯誤的,但它可以防止其他用戶在第一個用戶仍在忙於更新時弄亂它。然而,在這個計劃中工作的人在詳細視圖中離開程序。他們不出去。

問題是當第二個程序用於分發形式發票上的項目時。它使用相同的主表記錄。因此無法做任何事情,因爲第一個程序仍然在EXCLUSIVE-LOCK中。

我的問題是...

如何防止用戶在第一個程序更改數據,如果主表中的記錄是在專用鎖,但實際上不讓它在專用鎖?在多個會話...

回答

1

這可能是更好的評論,但我沒有足夠的聲望值做出評論。抱歉。

一些注意事項:

  1. 樂觀鎖定 - 如果它是可行的您的情況 - 幾乎可以肯定是最好的解決方案。

  2. 如果你要一個isLocked字段添加到表中,你可能會想其他幾個領域:

    • 日期/時間的記錄被鎖定 - 否則過期時間戳
    • LockHolder - 所以你知道你是否擁有它。
  3. 過期可以是自動的(如使用cron掃描),或者可以被忽略,除非其他人想要記錄。設置鎖定的程序也必須足夠聰明,以檢查它是否仍然存在。它變得複雜。

  4. 有時候不方便對錶進行模式更改,或者有太多需要更改的表。在這些情況下,您可以將這些字段添加到單獨的LockIt表中。一張桌子可以處理所有其他桌子的這些鎖。

旁白:
我們也用我們的LOCKIT表另一個目的:確保只有一個給定的程序副本可以同時運行。 (通常這是針對cron作業或批處理守護進程的。)該程序獨佔地鎖定LockIt表中的特定記錄(但不啓動事務!),只要程序正在運行,該程序就會持有該鎖。

+0

喜歡它。不幸的是,我嘗試了這一點,並與我的老闆解決上述問題他對兩個都說不。無論如何,我都從中學習,所以謝謝大家。 – Ivan

+0

那麼,你的老闆的要求是什麼?這是另一種可能性:爲保持記錄鎖定的程序添加一個自動超時。如果(例如)30分鐘沒有活動,它可以退出。如果你真的想要看起來很棒,它甚至可以保存所做的任何更改 - 無論是表格本身還是單獨的跟蹤表格。如果有問題,可能有解決辦法;困難的部分有時會問正確的問題。 –

+0

他希望它保持原樣。畢竟,我只需確保在程序中被阻止的所有內容都按下ctrl-c後即可撤銷。我做到了。 – Ivan

0

很可能,您的交易範圍是錯誤的。我會繼續,並假設您正試圖派發開發票計劃。那麼你不能,因爲記錄仍然被鎖定。機會是你的整個程序是一個交易,只要屏幕運行,記錄就會保持鎖定狀態。嘗試並重新訪問更新,在DO TRANSACTION塊中放入真正的更新操作,將MESSAGE TRANSACTION語句置於不同位置並查看結果。這將幫助您找到進度導致「相信」記錄仍然需要被鎖定的點。

+0

你說得很對。我已經在程序中找到了這些地方。在這些點上,記錄只被讀取。不需要獨佔鎖。該程序是故意使用排他鎖讀取記錄,以防止其他最終用戶進入。---------------查找第一個「表」WHERE「blablabla」EXLCUSIVE-LOCK NO-等待沒有錯誤====>如果鎖定「表」然後返回不適用............這就是它所服務的。所以我需要找到一種方法來阻止其他最終用戶讀取/更新,而不會阻止進程中的調度。 – Ivan

+0

在我目前工作的公司中,我們使用AppServer,因此如果您知道這些工作如何,那麼您知道我們無法持有鎖。那麼,我們所做的是有一個字段,說明記錄被鎖定。因此,其他用戶無法在發票或派發時更改訂單,就像您提到的那樣。如果您可以更改模式,則可以使用char或boolean字段。如果你不這樣做,這實際上是最簡單的解決方案,那麼當用戶發佈或修改發票記錄時,您必須將鎖持有的範圍專門映射到點。 – bupereira

+0

這就是我想到的同樣的解決方案。首先要確保這種事情不存在進展中的某些東西。謝謝bupereira ... – Ivan

-1

我假設你沒有使用應用服務器,因爲在這種情況下,這種行爲很可能不會成爲問題。

一種解決方案可能是轉變爲「樂觀鎖定」方法。這意味着你從「無鎖」開始,一旦你需要改變記錄,你將鎖升級到EXCLUSIVE-LOCK。這種方法可行,但您需要確保記錄仍然存在,並且不會被其他用戶更改。

取決於您的發票實際更改的頻率,這可能(或可能不)成爲解決方案。如果偶爾發生事故,這可能是一個可行的解決方案。如果它經常發生(每天左右),您需要做其他事情。一個樂觀的方法

基本僞代碼:

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.

+0

感謝您的意見。我非常喜歡樂觀的態度。然而,這個特定的問題,在我們測試獨佔鎖的時候,記錄根本不應該在「EXCLUSIVE-LOCK」中。沒有更新/添加/刪除。它唯一的目的是阻止其他最終用戶使用相同的形式發票的相同程序。目前的問題在於,它阻止了其他程序中使用相同記錄的其他所有人,他們應該能夠訪問它。發送應該能夠發送,而其他人不能混淆發票,而有人忙着它。 – Ivan