DBMS_LOCK PACKAGE In Oracle
INTRODUCTION:
This package is used for managing lock operation in PLSQL:
- LOCK
- CONVERSION
- RELEASE
SUBPROGRAMS OF DBMS_LOCK PACKAGE:
- ALLOCATE_UNIQUE PROCEDURE
- REQUEST FUNCTION
- CONVERT FUNCTION
- RELEASE FUNCTION
- SLEEP PROCEDURE
ALLOCATE_UNIQUE PROCEDURE:
- The ALLOCATE_UNIQUE procedure returns a unique handle to a lock specified by the lockname parameter.
- This handle can be used to identify the locks in call to other DBMS_LOCK programs.
SYNTAX:
--DBMS_LOCK PACKAGE In Oracle: DBMS_LOCK.ALLOCATE_UNIQUE
PROCEDURE DBMS_LOCK.ALLOCATE_UNIQUE(LOCKNAME IN VARCHAR2,
LOCKHANDLE OUT VARCHAR2,
EXPIRATION_SECS IN INTEGER DEFAULT
86400
); - LOCKNAME –> Name of the lock for which you want to generate an unique id.
- LOCKHANDLE –> Unique handle to lock by name
- EXPIRATION_SECS –> Length of time to leave the lock allocated.
RESTRICTIONS:
- Locknames can be 128 characters long and are case-sensitive.
- Locknames must not start with "ORA$" as these are reserved for oracle
- ALLOCATE_UNIQUE procedure always perform a commit so it cannot be called from TRIGGER.
--DBMS_LOCK PACKAGE In Oracle: Example CREATE OR REPLACE PACKAGE EMPLOYEE_ACCESS IS FUNCTION GET_EMP_LOCK_HANDLE RETURN VARCHAR2; END EMPLOYEE_ACCESS; /
--DBMS_LOCK PACKAGE In Oracle: Example
CREATE OR REPLACE PACKAGE BODY EMPLOYEE_ACCESS
IS
EMP_LOCKNAME VARCHAR2(128) := 'EMP_LOCK';
EMP_LOCKHANDLE VARCHAR2(128);
--
FUNCTION GET_EMP_LOCK_HANDLE
RETURN VARCHAR2
IS
BEGIN
IF EMP_LOCKHANDLE IS NULL THEN
DBMS_LOCK.ALLOCATE_UNIQUE (LOCKNAME => EMP_LOCKNAME,
LOCKHANDLE => EMP_LOCKHANDLE
);
END IF;
RETURN EMP_LOCKHANDLE;
END GET_EMP_LOCK_HANDLE;
END EMPLOYEE_ACCESS;
/ REQUEST FUNCTION:
- The REQUEST function is used to acquire a lock in the mode specified by lockmode parameter.
- If the lock cannot be acquired in the requested mode within the specified time the function returns a non-zero return value.
SYNTAX:
The first parameter of REQUEST function is overloaded. The first parameter is :
- either identify the lock by an id (integer)
- or identify the lock by lockhandle (varchar2)
--DBMS_LOCK PACKAGE In Oracle: DBMS_LOCK.REQUEST
DBMS_LOCK.REQUEST(ID INTEGER,
LOCKMODE INTEGER DEFAULT X_MODE,
TIMEOUT INTEGER DEFAULT MAXWAIT,
RELEASE_ON_COMMIT BOOLEAN DEFAULT FALSE)
RETURN INTEGER;
DBMS_LOCK.REQUEST(LOCKHANDLE VARCHAR2,
LOCKMODE INTEGER DEFAULT X_MODE,
TIMEOUT INTEGER DEFAULT MAXWAIT,
RELEASE_ON_COMMIT BOOLEAN DEFAULT FALSE)
RETURN INTEGER;
PARAMETER DESCRIPTIONS:
- ID :-> Numeric id of the lock
- LOCKHANDLE :-> Handle for lock returned by DBMS_LOCK.ALLOCATE_UNIQUE
- LOCKMODE :-> Locking mode requested for lock
- TIMEOUT :-> Time in second to wait for successful conversion.
- RELEASE_ON_COMMIT :-> If TRUE, release lock automatically on COMMIT or ROLLBACK.
DESCRIPTION OF RETURN VALUES OF FUNCTION:
- 0 –> Success
- 1 –> Timed out
- 2 –> Dead Lock
- 3 –> Parameter error
- 4 –> Do not own lock; cannot convert
- 5 –> Illegal lock handle
--DBMS_LOCK PACKAGE In Oracle: Example CREATE OR REPLACE PACKAGE EMPLOYEE_ACCESS IS FUNCTION GET_EMP_LOCK_HANDLE RETURN VARCHAR2; PROCEDURE LOCK_EMP(P_RETURN_CODE OUT INTEGER); END EMPLOYEE_ACCESS; /
--DBMS_LOCK PACKAGE In Oracle: Example
CREATE OR REPLACE PACKAGE BODY EMPLOYEE_ACCESS
IS
EMP_LOCKNAME VARCHAR2(128) := 'EMP_LOCK';
EMP_LOCKHANDLE VARCHAR2(128);
--
FUNCTION GET_EMP_LOCK_HANDLE
RETURN VARCHAR2
IS
BEGIN
IF EMP_LOCKHANDLE IS NULL THEN
DBMS_LOCK.ALLOCATE_UNIQUE (LOCKNAME => EMP_LOCKNAME,
LOCKHANDLE => EMP_LOCKHANDLE
);
END IF;
RETURN EMP_LOCKHANDLE;
END GET_EMP_LOCK_HANDLE;
PROCEDURE LOCK_EMP(P_RETURN_CODE OUT INTEGER)
IS
TEMP_LOCKHANDLE EMP_LOCKHANDLE%TYPE := GET_EMP_LOCK_HANDLE;
CALL_STATUS INTEGER;
BEGIN
CALL_STATUS := DBMS_LOCK.REQUEST(LOCKHANDLE => TEMP_LOCKHANDLE,
LOCKMODE => DBMS_LOCK.X_MODE,
TIMEOUT => 5,
RELEASE_ON_COMMIT => TRUE);
P_RETURN_CODE := CALL_STATUS;
END LOCK_EMP;
END EMPLOYEE_ACCESS;
/ CONVERT FUNCTION:
- The CONVERT function is used to convert a previously acquired lock to the mode specified by the lockmode parameter.
- If the mode conversion cannot be granted within specified time then the function returns a non-zero value.
- Just like REQUEST function, the first parameter of CONVERT function is overloaded. It is used to identify the lock either by integer or varchar2.
SYNTAX:
--DBMS_LOCK PACKAGE In Oracle: DBMS_LOCK.CONVERT
FUNCTION DBMS_LOCK.CONVERT(ID INTEGER,
LOCKMODE INTEGER,
TIMEOUT NUMBER DEFAULT MAXWAIT
) RETURN INTEGER;
FUNCTION DBMS_LOCK.CONVERT(LOCKHANDLE VARCHAR2,
LOCKMODE INTEGER,
TIMEOUT NUMBER DEFAULT MAXWAIT
) RETURN INTEGER; PARAMETER DESCRIPTIONS:
- ID :–> Numeric id of the lock
- LOCKHANDLE :-> Handle for lock returned by DBMS_LOCK.ALLOCATE_UNIQUE
- LOCKMODE :-> Locking mode to which to convert the lock
- TIMEOUT :-> Time in second to wait for successful conversion.
DESCRIPTION OF RETURN VALUES OF FUNCTION:
- 0 –> Success
- 1 –> Timed out
- 2 –> Dead Lock
- 3 –> Parameter error
- 4 –> Do not own lock; cannot convert
- 5 –> Illegal lock handle
--DBMS_LOCK PACKAGE In Oracle: Example
DECLARE
CALL_STATUS INTEGER;
BEGIN
CALL_STATUS := DBMS_LOCK.CONVERT(9999, DBMS_LOCK.NL_MODE, 0);
IF CALL_STATUS = 0 THEN
DBMS_OUTPUT.PUT_LINE('SUCCESS');
ELSE
IF CALL_STATUS = 1 THEN
DBMS_OUTPUT.PUT_LINE('FAIL DUE TO TIME OUT');
ELSIF CALL_STATUS = 2 THEN
DBMS_OUTPUT.PUT_LINE('FAIL DUE TO DEAD LOCK');
ELSIF CALL_STATUS = 3 THEN
DBMS_OUTPUT.PUT_LINE('FAIL DUE TO PARAMETER ERROR');
ELSIF CALL_STATUS = 4 THEN
DBMS_OUTPUT.PUT_LINE('FAIL DUE TO DO NOT OWN LOCK OR UNABLE TO CONVERT');
ELSIF CALL_STATUS = 5 THEN
DBMS_OUTPUT.PUT_LINE('FAIL DUE TO ILLEGAL LOCK HANDLE');
END IF;
END IF;
END;
/ RELEASE FUNCTION:
- RELEASE function releases a previously acquired lock.
- Only parameter of RELEASE function is overloaded. Its used to identify the lock either by integer or varchar2.
SYNTAX:
FUNCTION DBMS_LOCK.RELEASE(ID INTEGER) RETURN INTEGER;
FUNCTION DBMS_LOCK.RELEASE(LOCKHANDLE VARCHAR2) RETURN INTEGER;
PARAMETER DESCRIPTION:
- ID :–> Numeric id of the lock
- LOCKHANDLE :–> Handle for lock returned by ALLOCATE_UNIQUE
DESCRIPTION OF RETURN VALUES OF FUNCTION:
- 0 –> Success
- 3 –> Parameter error
- 4 –> Do not own lock; cannot release
- 5 –> Illegal lock handle
--DBMS_LOCK PACKAGE In Oracle: Example CREATE OR REPLACE PACKAGE EMPLOYEE_ACCESS IS FUNCTION GET_EMP_LOCK_HANDLE RETURN VARCHAR2; PROCEDURE LOCK_EMP(P_RETURN_CODE OUT INTEGER); PROCEDURE RELEASE_EMP(P_RETURN_CODE OUT INTEGER); END EMPLOYEE_ACCESS; /
--DBMS_LOCK PACKAGE In Oracle: Example
CREATE OR REPLACE PACKAGE BODY EMPLOYEE_ACCESS
IS
EMP_LOCKNAME VARCHAR2(128) := 'EMP_LOCK';
EMP_LOCKHANDLE VARCHAR2(128);
TEMP_LOCKHANDLE EMP_LOCKHANDLE%TYPE := GET_EMP_LOCK_HANDLE;
CALL_STATUS INTEGER;
--
FUNCTION GET_EMP_LOCK_HANDLE
RETURN VARCHAR2
IS
BEGIN
IF EMP_LOCKHANDLE IS NULL THEN
DBMS_LOCK.ALLOCATE_UNIQUE (LOCKNAME => EMP_LOCKNAME,
LOCKHANDLE => EMP_LOCKHANDLE
);
END IF;
RETURN EMP_LOCKHANDLE;
END GET_EMP_LOCK_HANDLE;
PROCEDURE LOCK_EMP(P_RETURN_CODE OUT INTEGER)
IS
BEGIN
CALL_STATUS := DBMS_LOCK.REQUEST(LOCKHANDLE => TEMP_LOCKHANDLE,
LOCKMODE => DBMS_LOCK.X_MODE,
TIMEOUT => 5,
RELEASE_ON_COMMIT => TRUE);
P_RETURN_CODE := CALL_STATUS;
END LOCK_EMP;
PROCEDURE RELEASE_EMP(P_RETURN_CODE OUT INTEGER)
IS
BEGIN
CALL_STATUS := DBMS_LOCK.RELEASE(LOCKHANDLE => TEMP_LOCKHANDLE);
P_RETURN_CODE := CALL_STATUS;
END RELEASE_EMP;
END EMPLOYEE_ACCESS;
/ SLEEP PROCEDURE:
- SLEEP procedure suspends the session for the no of seconds specified in seconds parameter.
- This procedure can be specified in hundredth part of a second e.g. 1.25, 1.49 etc.
SYNTAX:
PROCEDURE DBMS_LOCK.SLEEP(SECONDS NUMBER);
- Do not specify a null value for seconds parameter. It will raise ORA-00600 error.
BEGIN DBMS_LOCK.SLEEP(10); END; /