Ravinath
Ravinath

Reputation: 65

What are PERSISTENT Procedures in Progress 4GL?

I want to know what is exactly happening in the following code bit,

IF THIS-PROCEDURE:PERSISTENT 
THEN 
    DELETE PROCEDURE THIS-PROCEDURE.

Actullay I have to fix a bug in a kind of complex old-coded Progress GUI application. Breifly the scenario, The system is holding various details about members. Among them there is a field for relationships and you could switch to the relation record by clicking a switch button. So the issue is after you switching to the relation record and comeout from the records system keeps a lock in the relation record where we switched in. I am unable to post anycode as it is massive and complex to show the issue with code but if anyone could get the head around this, you may be able to put me into right direction to sort out this issue. I am expecting an answer like what would be the key things to check to investigate this kind of an issue? Any help would be highly appreciated.

Upvotes: 0

Views: 3828

Answers (2)

TheMadDBA
TheMadDBA

Reputation: 436

Tom gave you a good description of persistent and also pointed out the most likely issue with the code (record scoping and not a persistent procedure issue).

I like to go one step further than Tom suggests and use strong scoping because:

1) The compiler will warn you about attempts to increase the scope 2) It works in both internal procedures and old style top down code

define buffer bfCustomer for Customer.

/*- a bfCustomer reference here gets a compiler error -*/

do for bfCustomer transaction:
   find first bfCustomer exclusive-lock no-error.
   assign bfCustomer.name = "testme".
end.

/*- a bfCustomer reference here gets a compiler error -*/

Upvotes: 2

Tom Bascom
Tom Bascom

Reputation: 14020

A persistent procedure is one which stays in memory after its initial RUN completes. (Similar to ancient "terminate and stay resident" procedures in DOS...)

The following is over-simplified but may help:

The body of the procedure can be thought of as the "constructor".

Code like that which you show is generally part of an internal procedure (a "method") that serves as the destructor.

Other procedures which know the handle of a persistent procedure can run its methods. "RUN xyz IN proc-handle." (You can avoid the need to know the handle by establishing a persistent procedure as a "session super procedure".)

Your locking problem is probably due to poor record scope. There is probably a reference to the record which is scoped to the procedure as a whole. Some method is then "borrowing" that record scope from the larger procedure and modifying it which requires a lock. The lock is then scoped to the procedure rather than the method.

One trick that I, personally, find helpful is to write internal procedures thusly:

procedure xyz:

  define parameter cnum  as integer no-undo.
  define parameter cname as character no-undo.

  define buffer customer for customer.  /* this is the "trick" */

  find customer exclusive-lock where custNum = cnum.
  custName = cname.

end.

The "define buffer" restricts all references to "customer" to that internal procedure (method). This prevents accidental record scope leaks.

Upvotes: 2

Related Questions