Read consistency ensures that the query results are consistent with the data at the time when the query is initiated, regardless of whether other transactions have changed the data during the query.
Assume that we have the following function to calculate the total salary of the department based on the department id:
- Create or replace function sum2 (p_deptno in number)
- Return number is -- PRAGMA AUTONOMOUS_TRANSACTION;
- Rochelle ret number;
- BEGIN
- Dbms_lock.sleep (5 );
- -- DBMS_BACKUP_RESTORE.SLEEP (5 );
- Dbms_output.put_line (systimestamp );
- Select sum (sal)
- INTO l_ret
- FROM emp
- WHERE deptno = p_deptno;
- RETURN l_ret;
- END sum2;
Then we open a session (s1) and execute the following query (q1 ):
- SELECT deptno
- , SUM (sal)
- , Sum2 (deptno)
- , Systimestamp
- FROM emp
- Group by deptno;
During q1 execution, we opened a new session (s2), executed the update command, and submitted:
- SQL> update empSetSal = sal + 1;
- 14 rows updated
- SQL> commit;
- Commit complete
- SQL>
Return to s1 and check the q1 execution result:
- SQL> SELECT deptno
- 2, SUM (sal)
- 3, sum2 (deptno)
- 4, systimestamp
- 5 FROM emp
- 6 group by deptno;
- Deptno sum (SAL) SUM2 (DEPTNO) incluimestamp
- ------------------------------------------------------------------------------------------------------------
- 30 9400 9406 24-JUN-11 08.31.19.722000 PM +
- 20 10875 10880 24-JUN-11 08.31.19.722000 PM +
- 10 8750 8753 24-JUN-11 08.31.19.722000 PM +
- SQL>
We found that the results of sum (sal) and sum2 (deptno) are inconsistent.
When we apply a user-defined function to an SQL statement, which takes a long time to execute and some other dml changes some tables in the SQL statement during this time, this inconsistency will be reflected.
Set transaction read only can be used to avoid such inconsistency. For details, refer to my article below:
Oracle PL/SQL: SET TRANSACTION READ ONLY (TRANSACTION isolation)