What is PRAGMA ?
PRAGMA is a language construct that specifies how a compiler (or assembler or interpreter) should process its input. PRAGMA keyword in PLSQL is used to direct compiler to work differently when compared to the normal code. Pragmas are processed at compile time, not at run time.
What is AUTONOMOUS_TRANSACTION ?
The AUTONOMOUS_TRANSACTION pragma changes the way a subprogram works within a transaction. A subprogram marked with this pragma can do SQL operations and commit or roll back those operations, without committing or rolling back the data in the main transaction. The statement clearly states that autonomous transaction executes independent of main transaction. The concept was crystal clear to me and I had used it extensively in designing some of the solution. Very recently a question raised in my mind.
Will the changes made by autonomous transaction be visible in the main transaction ? I didn't have an answer and hence tried to do a research. Let try to get an answer using the below example.
Environment Setup
DROP TABLE emp_data;
/
CREATE TABLE emp_data
(
empno NUMBER,
ename VARCHAR2(10),
location VARCHAR2(10)
);
/
INSERT INTO emp_data
(empno,
ename,
location)
VALUES (1,
'Scott',
'US');
/
CREATE OR replace PROCEDURE Insert_emp(p_name IN VARCHAR2,
p_loc IN VARCHAR2)
IS
PRAGMA autonomous_transaction;
BEGIN
INSERT INTO emp_data
VALUES ( (SELECT Max(empno)
FROM emp_data),
p_name,
p_loc);
COMMIT;
END;
/
show errors
/
CREATE OR replace PROCEDURE Add_emp(p_name IN VARCHAR2,
p_loc IN VARCHAR2)
IS
PROCEDURE Show_emp
IS
BEGIN
FOR data IN (SELECT *
FROM emp_data) LOOP
dbms_output.Put_line('EmpID : '
|| data.empno
|| ' Ename : '
|| data.ename
||' Location : '
|| data.location);
END LOOP;
END;
BEGIN
dbms_output.Put_line('****Before Insert****');
show_emp;
Insert_emp(p_name, p_loc);
dbms_output.Put_line('****After Insert****');
show_emp;
END;
/
show errors
/
Lets try executing the code and see the output.
set serveroutput ON
BEGIN
Add_emp('Tiger', 'UK');
END;
Output
****Before Insert****
EmpID : 1 Ename : Scott Location : US
****After Insert****
EmpID : 1 Ename : Scott Location : US
EmpID : 1 Ename : Tiger Location : UK
This answered by question . The example proves that changes made in autonomous transactions are visible in main transaction.
My next question was , Can we stop the changes made by autonomous transaction being show in the main transaction ? It is possible by controlling transaction visibility i.e. using transaction isolation level.
Lets see how this can be achieved.
ALTER SESSION SET ISOLATION_LEVEL = SERIALIZABLE;
execute add_emp('Steve','Aus');
Output
****Before Insert****
EmpID : 1 Ename : Scott Location : US
EmpID : 1 Ename : Tiger Location : UK
****After Insert****
EmpID : 1 Ename : Scott Location : US
EmpID : 1 Ename : Tiger Location : UK
With this example i could conclude that changes made by an autonomous transaction become visible to other transactions when the autonomous transaction commits. The changes also become visible to the main transaction when it resumes, but only if its isolation level is set to READ COMMITTED (the default). If you set the isolation level of the main transaction to SERIALIZABLE, changes made by its autonomous transactions are not visible to the main transaction when it resumes.
good post
ReplyDelete--------
شركة عزل اسطح بجدة