Kbase 15160: What is the bleeding record lock (-brl Startup Option) and how it affects Record Locking Behavior
Autor |
  Progress Software Corporation - Progress |
Acesso |
  Público |
Publicação |
  16/10/2008 |
|
Status: Verified
GOAL:
What is the bleeding record lock (-brl Startup Option) and how it affects Record Locking Behavior
FACT(s) (Environment):
Progress 7.x
Progress 4GL
FIX:
There has been a change in the way Progress handles the release of record locks with multiple buffers.
If your application depends on the earlier default strategy, it might behave differently under later versions of Progress.
You can choose to retain the previous behavior by making use of a new start-up option (-brl) that is provided for this purpose.
Prior to Version 7.3B, the behavior is as follows:
If an application reads the same record into two different buffers, one with a NO-LOCK and one with a SHARE-LOCK (or EXCLUSIVE-LOCK), then releases the
lock, the record will remain SHARE-LOCKed even though the only buffer left holding the record requested it with NO-LOCK. This can be shown by the following
example using the demo or sports database:
DEFINE BUFFER xcust FOR customer.
DEFINE VARIABLE crid AS RECID NO-UNDO.
FOR EACH customer NO-LOCK:
ASSIGN crid = RECID(customer).
MESSAGE "got customer " + STRING(crid) " no-lock".
PAUSE.
DO FOR xcust:
MESSAGE "in DO block".
PAUSE.
FIND xcust WHERE RECID(xcust) = crid SHARE-LOCK.
MESSAGE "share-locked xcust recid " + STRING(RECID(xcust)).
PAUSE.
RELEASE xcust.
END.
MESSAGE "out of DO block, xcust released".
PAUSE.
RELEASE customer.
MESSAGE "released customer buffer".
PAUSE.
END.
NOTE: The PAUSE statements allow you to examine the lock status by running promon or a separate procedure which attempts to place an EXCLUSIVE-LOCK on the first customer record while this procedure is run.
When running PROGRESS with versions prior to 7.3B, you will see that the record lock isn't downgraded to no-lock until the second buffer is released. Note that there is no active transaction in this example. The use of multiple buffers
causes the record lock to "bleed" through to all buffers in which the data record is active.
With Version 7.3B and later, this behavior can be continued, if desired, by using the -brl start-up option. If this option is *not* used, any other buffers in which the same data record is active are restored to the lock type they
originally requested once the SHARE-LOCK is downgraded.
In other words, in the above example, the lock will be released on the customer buffer when the xcust buffer is released.
The "bleeding lock" behavior is often encountered in a less obvious situation where the NO-LOCK access is done in one procedure which calls another procedure to perform the SHARE-LOCK or EXCLUSIVE-LOCK access using another "copy" of the buffer.
This might be done as follows:
/* main.p */
FIND FIRST customer NO-LOCK.
/* some processing */
RUN second.p.
MESSAGE "back in main".
PAUSE.
/* second.p */
MESSAGE "in second.p".
PAUSE.
FIND FIRST customer SHARE-LOCK.
MESSAGE "share-locked first customer".
PAUSE.
/* ends the scope of the 2nd "copy" of customer buffer
but the lock persists on main.p copy prior to 7.3B */
This second example will have the same behavior as the first. Although the customer buffer in second.p is scoped to the procedure, the lock "bleeds" to the customer buffer scoped to the main.p because the same data record is held active in that buffer when the lock is released at the end of the procedure second.p.
In version 7.3B and later versions, this will not occur and the customer buffer in main.p will revert to NO-LOCK status at the end of second.p.
The COMPILE statement, when used with the LISTING option indicates blocks that have records scoped to them in your procedures.