Salesforce

How to debug "Increase -L" error (915), record locking, transactions?

« Go Back

Information

 
TitleHow to debug "Increase -L" error (915), record locking, transactions?
URL NameP100701
Article Number000132930
EnvironmentProduct: OpenEdge
Version: All supported versions
OS: All supported platforms
Question/Problem Description
How to debug "Increase -L" error (915), record locking, transactions?
Resolving multi-user record locking and scoping issues (915)
How to debug the Lock table overflow 915 error?
Troubleshooting Error (915).
Possible causes of the Lock table overflow error (915).
What causes a Lock Table overflow?
Application code raising excessive Locks for prolonged periods of time
Steps to Reproduce
Clarifying Information


 
Error MessageLock table overflow, increase -L on server (915)
Defect Number
Enhancement Number
Cause
Resolution

What Causes a Lock Table Overflow?

A Lock Table overflow is caused by record locking and scoping issues related to the size of transactions. When Lock table overflow, increase -L on server (915) occurs the application code is locking more records than the current Lock Table (-L) Database startup parameter currently allows. When the number of Lock Table entries is not explicitly set as a database startup parameter the default number of locks is 8192 which is rarely sufficient for multi-user production environments.

Exceeding -L is not a usual situation, it indicates that the Application logic needs review. The most likely reasons that many records are being locked is either that:

  1. The transaction scope is very large.
  2. The records are being held SHARE-LOCK'ed after the transaction because the record scope has not ended.
  3. An increase in the number of database users

When the lock table is exceeded, the built in overhead in shared memory (-Mxs) is used to increase the size of the lock table. When the excess shared memory is used up, this results in a fatal error and the database shuts down:  Out of free shared memory. Use -Mxs to increase. (6495). 

In earlier Progress versions, the Lock Table size could continually creep up unnoticed.
In later OpenEdge versions, the lock table overflow message is raised every time the initial lock table allocation is exceeded. This provides more advanced warning that something needs to be fixed (whether it be the initial lock table size and/or the cause of the -L being exceeded) and diagnosed sooner before eventually excess shared memory is exceeded. 

Resolving multi-user record locking and scoping issues (915)

Increase -L

As a database grows, logically the amount of data within tables will grow. Even the best queries are expected to use a greater and greater number of locks as the number of records grows over time, unless the query is satisfied by a unique record. If the application transaction scope is designed correctly and is not locking records needlessly, then the Size of Lock Table (-L) needs to be increased. Since OpenEdge 10.1C it can be increased online, refer to Article What is proutil <dbname> -C  increaseto?

Increasing the -L database startup parameter will alleviate the problem initially. It will however result in more records remaining locked within the transaction, thereby creating a greater likelihood of other users having to wait before they can access locked records.

Increasing -Mxs to allow the Lock Table size to extend can be considered in addition to increasing the initial Lock Table size, but excess shared memory should not be relied on as it is used for overflow in other shared memory structures as well.  Each lock table entry size is 72 bytes for both 64 and 32 bit.

Review Application Transaction Scope

Running the procedure in single-user mode bypasses record-locking. If the process involves a very large transaction through necessity, consider running the procedure as a single-user batch process, or as a shared-memory batch process at a time when other users are not actively updating records.

Making transactions smaller within the procedure locks fewer records and avoids having to increase the lock table (-L) startup parameter disproportionately.

One method of narrowing the scope of the transaction is to put a DO TRANSACTION: block directly around the statement that updates the record. However, when the scope of the record being updated is higher than the scope of the transaction, a SHARE-LOCK is still held for each record until the end of the record scope. The RELEASE statement explicitly releases a SHARE-LOCK’ed record after the statement which updates the database has occurred.

What is a record's scope?

The record's scope is the block in which the record was first referenced in the procedure or calling procedure. The COMPILE with the LISTING option can be used to determine a record's scope. Any reference to a record, before the first block in the program, scopes that record to the procedure block. The procedure block does not end until program ends. Therefore, record locks being held until the end of the record scope are held for the duration of the program unless these locks are explicitly released the with the RELEASE statement.

What is transaction scope? 

The transaction scope is the outermost block with transaction properties that updates the database. Statements that update the database include:

UPDATE, CREATE, ASSIGN and SET.


Blocks with transaction properties include:

FOR EACH, REPEAT, PROCEDURE, DO TRANSACTION, a block that specifies EXCLUSIVE-LOCK and any block that has the TRANSACTION keyword.


FIND with an EXCLUSIVE-LOCK will also start a transaction, as the Progress compiler interprets the EXCLUSIVE-LOCK as an intent to update the database.


Online Procedures and Utilities:

1.  Current Record Locks 

Identifying the user holding the most locks for an extended period assists in eventually finding the transaction code needing review. Record Locks being held can be found through:  

PROMON > Option 4. Record Lock Table


2.  Long running Transactions 

Identifying Transactions that run for extended periods of time assists in eventually isolating the transaction code needing review. Long running Transactions can be found through the VST _Trans and the _DbStatus VST reports on the Total Current and most used Locks. Refer to Articles:


3.  Active transactions in the procedure 

Identify Active transactions:

  • Only one Active transaction is ever allowed per user session at a time, the next transaction is started in the procedure is a sub-transaction. 
  • When a transaction is started in one procedure and it has not ended when a sub-procedure is called, new transactions in the sub-procedure will also be sub transactions. 
  • The TRANSACTION function can be used to determine if there is already an active transaction in the procedure. 

 

DO:
 MESSAGE "transaction active  ? " TRANSACTION.
END.

DO TRANSACTION:
 MESSAGE "transaction active  ? " TRANSACTION.
END.


4.  COMPILE LISTING  

When the procedure is locking more records than expected a COMPILE LISTING provides information on where records and transactions within the program are scoped.

COMPILE <procedure> LISTING <listfile>

 
5. Use 4GLTrans and 4GLTrace logging

On the Client side, in OpenEdge 10 and later, use 4GLTrans and 4GLTrace log entry types with -clientlog to report where transactions begin and end.  

Example, a Client session started with:
 

prowin32.exe -p progs\speedtest.p -db db\sports2000 -errorstack -clientlog mylog.lg -logginglevel 2 -logentrytypes DB.Connects,4GLMessages,4GLTrans,4GLTrace


Creates a mylog.lg file with entries of the form:

15:02:18.048] P-012876 T-011196 2 4GL 4GLTRACE       Run slow [Main Block - progs\speedtest.p @ 25]
15:02:18.048] P-012876 T-011196 3 4GL 4GLTRANS       BEGIN TRANS 5 [SLOW progs\speedtest.p @ 13]
15:02:19.085] P-012876 T-011196 3 4GL 4GLTRANS       END TRANS 5 [SLOW progs\speedtest.p @ 17]

For further details refer to Article How to determine transaction scope at runtime   

6. Periodically review and evaluate database startup parameters

Schedule database startup parameters reviews, particularly when a large amount of data or large increase in database users has occurred.  Either of these two situations will increase the number of locks that must be supported by the database during concurrent use.

7. Utility for monitoring users' lock count for forensic value

The below link brings you to an article with a utility that can be run proactively to monitor the locking table and periodically output various user information including the number of locks held by each user connection.  This also provides stack information from the processes in order to identify which code is running.  This should help to understand (after the fact) who was holding the largest number of locks, in order to understand where to start looking for potentially problematic code, or to confirm that the -L setting is presently too small.

How to monitor for users with the largest number of locks in a OpenEdge database?

 

Workaround
Notes
Keyword Phrase
Last Modified Date12/4/2024 8:45 PM

Powered by