Oracle8i Supplied Packages Reference Release 8.1.5 A68001-01 |
|
Oracle Lock Management services for your applications are available through procedures in the DBMS_LOCK
package. You can request a lock of a specific mode, give it a unique name recognizable in another procedure in the same or another instance, change the lock mode, and release it.
Because a reserved user lock is the same as an Oracle lock, it has all the functionality of an Oracle lock, such as deadlock detection. Be certain that any user locks used in distributed transactions are released upon COMMIT
, or an undetected deadlock may occur.
User locks never conflict with Oracle locks because they are identified with the prefix "UL". You can view these locks using the Enterprise Manager lock monitor screen or the appropriate fixed views. User locks are automatically released when a session terminates.
The lock identifier is a number in the range of 0 to 1073741823.
Some uses of user locks:
DBMS_LOCK
is most efficient with a limit of a few hundred locks per session. Oracle strongly recommends that you develop a standard convention for using these locks in order to avoid conflicts among procedures trying to use the same locks. For example, include your company name as part of your lock names.
There might be operating system-specific limits on the maximum number of total locks available. This must be considered when using locks or making this package available to other users. Consider granting the EXECUTE
privilege only to specific users or roles.
A better alternative would be to create a cover package limiting the number of locks used and grant EXECUTE
privilege to specific users. An example of a cover package is documented in the DBMSLOCK.SQL
package specification file.
Oracle provides two facilities to display locking information for ongoing transactions within an instance:
nl_mode constant integer := 1; ss_mode constant integer := 2; -- Also called 'Intended Share' sx_mode constant integer := 3; -- Also called 'Intended Exclusive' s_mode constant integer := 4; ssx_mode constant integer := 5; x_mode constant integer := 6;
These are the various lock modes (nl -> "NuLl", ss -> "Sub Shared", sx -> "Sub eXclusive", s -> "Shared", ssx -> "Shared Sub eXclusive", x -> "eXclusive").
A sub-share lock can be used on an aggregate object to indicate that share locks are being aquired on sub-parts of the object. Similarly, a sub-exclusive lock can be used on an aggregate object to indicate that exclusive locks are being aquired on sub-parts of the object. A share-sub-exclusive lock indicates that the entire aggregate object has a share lock, but some of the sub-parts may additionally have exclusive locks.
When another process holds "held", an attempt to get "get" does the following:
maxwait constant integer := 32767;
The constant maxwait
waits forever.
This procedure allocates a unique lock identifier (in the range of 1073741824 to 1999999999) given a lock name. Lock identifiers are used to enable applications to coordinate their use of locks. This is provided because it may be easier for applications to coordinate their use of locks based on lock names rather than lock numbers.
If you choose to identify locks by name, you can use ALLOCATE_UNIQUE
to generate a unique lock identification number for these named locks.
The first session to call ALLOCATE_UNIQUE
with a new lock name causes a unique lock ID to be generated and stored in the dbms_lock_allocated
table. Subsequent calls (usually by other sessions) return the lock ID previously generated.
A lock name is associated with the returned lock ID for at least expiration_secs
(defaults to 10 days) past the last call to ALLOCATE_UNIQUE
with the given lock name. After this time, the row in the dbms_lock_allocated
table for this lock name may be deleted in order to recover space. ALLOCATE_UNIQUE
performs a commit.
DBMS_LOCK.ALLOCATE_UNIQUE ( lockname IN VARCHAR2, lockhandle OUT VARCHAR2, expiration_secs IN INTEGER DEFAULT 864000);
ORA-20000
, ORU-10003:
Unable to find or insert lock <lockname
> into catalog dbms_lock_allocated
.
None.
This function requests a lock with a given mode. REQUEST
is an overloaded function that accepts either a user-defined lock identifier, or the lock handle returned by the ALLOCATE_UNIQUE
procedure.
DBMS_LOCK.REQUEST( id IN INTEGER || lockhandle IN VARCHAR2, lockmode IN INTEGER DEFAULT X_MODE, timeout IN INTEGER DEFAULT MAXWAIT, release_on_commit IN BOOLEAN DEFAULT FALSE, RETURN INTEGER;
The current default values, such as X_MODE
and MAXWAIT
, are defined in the DBMS_LOCK
package specification.
Parameter | Description |
---|---|
id or lockhandle |
User assigned lock identifier, from 0 to 1073741823, or the lock handle, returned by |
lockmode |
Mode that you are requesting for the lock. The available modes and their associated integer identifiers are listed below. The abbreviations for these locks, as they appear in the V$ views and Enterprise Manager monitors are in parentheses. 5 - share row exclusive mode (ULRSX) Each of these lock modes is explained in Oracle8 Concepts. |
timeout |
Number of seconds to continue trying to grant the lock.
If the lock cannot be granted within this time period, then the call returns a value of 1 ( |
release_on_commit |
Set this parameter to Otherwise, the lock is held until it is explicitly released or until the end of the session. |
Return Value | Description |
---|---|
0 |
Success |
1 |
Timeout |
2 |
Deadlock |
3 |
Parameter error |
4 |
Already own lock specified by |
5 |
Illegal lock handle |
None.
This function converts a lock from one mode to another. CONVERT
is an overloaded function that accepts either a user-defined lock identifier, or the lock handle returned by the ALLOCATE_UNIQUE
procedure.
DBMS_LOCK.CONVERT( id IN INTEGER || lockhandle IN VARCHAR2, lockmode IN INTEGER, timeout IN NUMBER DEFAULT MAXWAIT) RETURN INTEGER;
Parameter | Description |
---|---|
id or lockhandle |
User assigned lock identifier, from 0 to 1073741823, or the lock handle, returned by |
lockmode |
New mode that you want to assign to the given lock. The available modes and their associated integer identifiers are listed below. The abbreviations for these locks, as they appear in the V$ views and Enterprise Manager monitors are in parentheses. 5 - share row exclusive mode (ULRSX) Each of these lock modes is explained in Oracle8 Concepts. |
timeout |
Number of seconds to continue trying to change the lock mode. If the lock cannot be converted within this time period, then the call returns a value of 1 (timeout). |
Return Value | Description |
---|---|
0 |
Success |
1 |
Timeout |
2 |
Deadlock |
3 |
Parameter error |
4 |
Don't own lock specified by |
5 |
Illegal lock handle |
None.
This function explicitly releases a lock previously acquired using the REQUEST
function. Locks are automatically released at the end of a session. RELEASE
is an overloaded function that accepts either a user-defined lock identifier, or the lock handle returned by the ALLOCATE_UNIQUE
procedure.
DBMS_LOCK.RELEASE ( id IN INTEGER) RETURN INTEGER; DBMS_LOCK.RELEASE ( lockhandle IN VARCHAR2) RETURN INTEGER;
Parameter | Description |
---|---|
id or lockhandle |
User assigned lock identifier, from 0 to 1073741823, or the lock handle, returned by |
Return Value | Description |
---|---|
0 |
Success |
3 |
Parameter error |
4 |
Do not own lock specified by |
5 |
Illegal lock handle |
None.
This procedure suspends the session for a given period of time.
DBMS_LOCK.SLEEP ( seconds IN NUMBER);
Parameter | Description |
---|---|
seconds |
Amount of time, in seconds, to suspend the session. The smallest increment can be entered in hundredths of a second; for example, 1.95 is a legal time value. |
This Pro*COBOL precompiler example shows how locks can be used to ensure that there are no conflicts when multiple people need to access a single device.
Any cashier may issue a refund to a customer returning goods. Refunds under $50 are given in cash; anything above that is given by check. This code prints the check. The one printer is opened by all the cashiers to avoid the overhead of opening and closing it for every check. This means that lines of output from multiple cashiers could become interleaved if we don't ensure exclusive access to the printer. The DBMS_LOCK
package is used to ensure exclusive access.
CHECK-PRINT
Get the lock "handle" for the printer lock:
MOVE "CHECKPRINT" TO LOCKNAME-ARR. MOVE 10 TO LOCKNAME-LEN. EXEC SQL EXECUTE BEGIN DBMS_LOCK.ALLOCATE_UNIQUE ( :LOCKNAME, :LOCKHANDLE ); END; END-EXEC.
Lock the printer in exclusive mode (default mode):
EXEC SQL EXECUTE BEGIN DBMS_LOCK.REQUEST ( :LOCKHANDLE ); END; END-EXEC.
We now have exclusive use of the printer, print the check:
...
Unlock the printer so other people can use it:
EXEC SQL EXECUTE BEGIN DBMS_LOCK.RELEASE ( :LOCKHANDLE ); END; END-EXEC.