07 Consistent vs. Current 모드 읽기

1. Consistent 모드 읽기와 Current 모드 읽기의 차이점
2. Consistent 모드로 갱신할 때 생기는 현상
3. Current 모드로 갱신할 때 생기는 현상
4. Consistent 모드로 읽고, Current 모드로 갱신할 때 생기는 현상.
5. Consistent 모드로 갱신대상을 식별하고, Current 모드로 갱신
6. 오라클에서 일관성 없게 값을 갱신하는 사례

1. Consistent 모드 읽기와 Current 모드 읽기의 차이점

[SQL_TRACE]

call     count       cpu    elapsed       disk      query    current        rows
------- ------  -------- ---------- ---------- ---------- ----------  ----------
Parse        2      0.00       0.00          0          0          0           0
Execute      2      0.55       0.56          0       3658       6632      251688
Fetch        0      0.00       0.00          0          0          0           0
------- ------  -------- ---------- ---------- ---------- ----------  ----------
total        4      0.55       0.57          0       3658       6632      251688

[AUTO_TRACE]
 Statistics
----------------------------------------------------------
         30  recursive calls
     291469  db block gets
       4293  consistent gets
         36  physical reads
   77169680  redo size
        835  bytes sent via SQL*Net to client
        780  bytes received via SQL*Net from client
          3  SQL*Net roundtrips to/from client
          1  sorts (memory)
          0  sorts (disk)
     125844  rows processed

2. Consistent 모드로 갱신할 때 생기는 현상

상황1

TX1TX2
update emp set sal = sal + 100 where empno=7788;t1
t2update emp set sal = sal\+ 200 where empno=7788;
commit;t3
t4commit;
  • select sal from emp where empno = 7788;
    • Consistent = 1200
    • ORACLE = 1300
3. Current 모드로 갱신할 때 생기는 현상

상황2

TX1TX2
update emp set sal = 2000 where empno=7788 and sal = 1000;t1
t2update emp set sal = 3000 where empno=7788 and sal = 2000;
commit;t3
t4commit;
  • select sal from emp where empno = 7788;
    • Current= 3000
    • ORACLE = 2000

상황3

TX1TX2
update t set no = no + 1 where no > 50000;t1
t2insert into t values (1000001,1000001);;
t3commit;
commit;t4
  • select count(no) from t where no > 50000;
    • Current = 500001
    • ORACLE = 50000
4. Consistent 모드로 읽고, Current 모드로 갱신할 때 생기는 현상.

오라클에서 Update 문을 수행하면, 대상 레코드를 읽을 때는 Consistent 모드로 읽고 실제 값을
변경할 떄는 Current 모드로 읽는다 따라서 대상 레코드를 읽기 위한 블록 액세스는 SQL 트레이스에서
Query 항목에서 계산되고, 값을 변경하기 위한 블록 액세스는 Current 항목에서 계산된다.

상황4

TX1TX2
update emp set sal = sal + 100 where empno=7788 and sal = 1000;t1
t2update emp set sal = sal + 200 where empno=7788 and sal = 1000;
commit;t3
t4commit;
  • select sal from emp where empno = 7788;
    • Consistent 모드로 읽고, Current 모드로 갱신 = 1200
    • ORACLE = 1100 TX2 : 0 rows updated
update emp set sal = sal + 200
where empno = 7788
and sal = 1000;
update
(
select sal from emp
where empno = 7788
and sal = 1000
)
set sal = sal + 200;
5. Consistent 모드로 갱신대상을 식별하고, Current 모드로 갱신
for c in모드
(
select rowid rid from empConsistent
where empno = 7788 and sal = 1000
)
loop
update emp set sal = sal + 200Current
where empno = 7788
and sal = 1000
and rowid = c.rid;
end loop;

1. select 는 Constistent 모드로 읽는다.
2. insert, update, delete , merge 는 Current 모드로 읽고 쓴다. 다만 갱신할 대상 레코드를 식별하는
작업 만큼은 Consistent으로 이루어진다.

6. 오라클에서 일관성 없게 값을 갱신하는 사례

SQL> select * from 계좌1;

  계좌번호 계좌명	    잔고
---------- ---------- ----------
       616 WQZUG	    1000
       526 GUXEV	    1000
       868 IGZC 	    1000
       812 QPSEP	    1000
       339 QDVORQ	    1000
       320 CUDXH	    1000
       173 AUDVT	    1000
       170 WFMUO	    1000
       956 TULB 	    1000
       989 JUVVHY	    1000
       992 GBDSP	    1000
       745 QCWEP	    1000
       743 AZZC 	    1000
       759 QZWNHY	    1000

14 rows selected.

Elapsed: 00:00:00.00
SQL> select * from 계좌2;

  계좌번호 계좌명	    잔고     총잔고
---------- ---------- ---------- ----------
       616 WQZUG	    1000       2000
       526 GUXEV	    1000       2000
       868 IGZC 	    1000       2000
       812 QPSEP	    1000       2000
       339 QDVORQ	    1000       2000
       320 CUDXH	    1000       2000
       173 AUDVT	    1000       2000
       170 WFMUO	    1000       2000
       956 TULB 	    1000       2000
       989 JUVVHY	    1000       2000
       992 GBDSP	    1000       2000
       745 QCWEP	    1000       2000
       743 AZZC 	    1000       2000
       759 QZWNHY	    1000       2000

14 rows selected.

SQL>  select 계좌1.잔고, 계좌2.잔고, 계좌2.총잔고
       , 계좌1.잔고+계좌2.잔고 총잔고2
  from   계좌1, 계좌2
  where  계좌1.계좌번호 = 170
  and    계좌2.계좌번호 = 계좌1.계좌번호 ;

      잔고	 잔고	  총잔고    총잔고2
---------- ---------- ---------- ----------
      1000	 1000	    2000       2000

TX1TX2
SQL> update 계좌1 set 잔고 = 잔고 + 100 where 계좌번호 = 170;t1
1 row updated.t1
SQL> update 계좌2 set 잔고 = 잔고 + 200 where 계좌번호 = 170;t2
1 row updated.t2
t3SQL> update 계좌2
t3set 총잔고 = 계좌2.잔고 + (select 잔고 from 계좌1 where 계좌번호 = 계좌2.계좌번호)
t3where 계좌번호 = 170;
SQL> commit;t4
t51 row updated.
t5SQL> commit;

22:43:22 SQL>  select 계좌1.잔고, 계좌2.잔고, 계좌2.총잔고
       , 계좌1.잔고+계좌2.잔고 총잔고2
  from   계좌1, 계좌2
  where  계좌1.계좌번호 = 170
  and    계좌2.계좌번호 = 계좌1.계좌번호 ;

      잔고	 잔고	  총잔고    총잔고2
---------- ---------- ---------- ----------
      1100	 1200	    2200       2300

Elapsed: 00:00:00.00

TX1TX2
SQL> update 계좌1 set 잔고 = 잔고 + 100 where 계좌번호 = 170;t1
1 row updated.t1
SQL> update 계좌2 set 잔고 = 잔고 + 200 where 계좌번호 = 170;t2
1 row updated.t2
t3SQL> update 계좌2
t3set 총잔고 = (select 계좌2.잔고 + 잔고 from 계좌1 where 계좌번호 = 계좌2.계좌번호)
t3where 계좌번호 = 170;
SQL> commit;t4
t51 row updated.
t5SQL> commit;

23:06:48 SQL>  select 계좌1.잔고, 계좌2.잔고, 계좌2.총잔고
       , 계좌1.잔고+계좌2.잔고 총잔고2
  from   계좌1, 계좌2
  where  계좌1.계좌번호 = 170
  and    계좌2.계좌번호 = 계좌1.계좌번호;

      잔고	 잔고	  총잔고    총잔고2
---------- ---------- ---------- ----------
      1100	 1200	    2300       2300

SQL계좌1.잔고 읽기 모드계좌2.잔고 읽기 모드비고
update 계좌2
set 총잔고 = 계좌2.잔고 +
(select 잔고 from 계좌1 where 계좌번호 = 계좌2.계좌번호)
where 계좌번호 = 170;
ConsistentCurrent쿼리 SCN 이후에 계좌1의 변동 내역이 무시됨
update 계좌2
set 총잔고 = (select 계좌2.잔고 + 잔고 from 계좌1 where 계좌번호 = 계좌2.계좌번호)
where 계좌번호 = 170;
CurrentCurrent계좌1의 현재값을 읽으나, delete 된경우 NULL 로 업데이트 됨

스칼라 서브쿼리는 특별한 이유가 없는 항 항상 Consistent 모드로 읽는다