Kbase P8443: Error 915: Resolving record locking and scoping issues
Autor |
  Progress Software Corporation - Progress |
Acesso |
  Público |
Publicação |
  27/11/2009 |
|
Status: Verified
SYMPTOM(s):
Error 915 running a procedure in multi-user mode.
Lock table overflow, increase -L on server (915)
Database in constant use.
Records are being actively updated continuously.
FACT(s) (Environment):
All Supported Operating Systems
Progress/OpenEdge Product Family
CAUSE:
Error 915 is caused by record locking and scoping issues as related to the size of PROGRESS transactions.
When Error 915 is in evidence, the application is locking more records than the server startup parameter (-L) currently allows. If you do not specify -L as a startup parameter on the PROGRESS SERVER (proserve command), PROGRESS sets the default number of locks to 8192.
Exceeding -L is not a "usual" situation, it can indicate misconfiguration/bugs
in the 4GL program. The most likely reasons that PROGRESS is locking a large number of records is either that:
1) The transaction is very large.
-OR-
2) The records are being held SHARE-LOCK'ed after the transaction because the record scope has not ended.
FIX:
If the application is designed correctly and is not locking records needlessly, then -L needs to be increased anyway. However if the program is locking more records than expected, then it should be debugged in the first instance. The
COMPILE <procedure> LISTING <listfile>
routine is useful in this regard.
Although increasing the -L startup parameter on the PROGRESS SERVER (proserve command) will get around the problem initially, this will result in more records remaining locked within the transaction, thereby creating a greater likelihood of other users attempting to access locked records.
Making transactions smaller within the procedure locks fewer records and avoids having to increase the lock table (-L) startup parameter or running in single-user mode. One method of lowering the scope of your transaction is to put a DO TRANSACTION: block directly around the statement that updates the record. If the scope of the record that is being updated is higher than the scope of the transaction, however, PROGRESS holds on to a SHARE-LOCK for each record until the end of the record scope. The RELEASE statement allows you to explicitly release a SHARE-LOCK'ed record after the statement which updates the database has occurred.
The record's scope is the block in which it was first referenced in your procedure or in a calling procedure. Use the COMPILE with the LISTING option to determine a record's scope. Note that 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 you explicitly release the lock with the RELEASE statement.
The transaction scope is the outermost block with transaction properties containing updates the database. Statements that update the database include:
ASSIGN, UPDATE, CREATE, ASSIGN and SET.
Please note that a FIND with the EXCLUSIVE-LOCK option will also start a transaction, as the Progress compiler interprets the EXCLUSIVE-LOCK as an intent to update the database.
Blocks with transaction properties include:
FOR EACH, REPEAT, PROCEDURE, DO TRANSACTION and any block that has the TRANSACTION keyword.
Use the TRANSACTION function to determine if there is already an active transaction in your procedure. Note that PROGRESS allows only one active transaction at a time, so the next transaction that you start in your procedure is actually a subtransaction. Also note that if you start a transaction in one procedure and it has not ended when you call a sub-procedure, new transactions in the sub-procedure will also be subtransactions.