1. Consistent 모드 읽기와 Current 모드 읽기의 차이점
2. Consistent 모드로 갱신할 때 생기는 현상
3. Current 모드로 갱신할 때 생기는 현상
4. Consistent 모드로 읽고, Current 모드로 갱신할 때 생기는 현상.
5. Consistent 모드로 갱신대상을 식별하고, Current 모드로 갱신
6. 오라클에서 일관성 없게 값을 갱신하는 사례
[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
상황1
TX1 | TX2 | |
---|---|---|
update emp set sal = sal + 100 where empno=7788; | t1 | |
t2 | update emp set sal = sal\+ 200 where empno=7788; | |
commit; | t3 | |
t4 | commit; |
상황2
TX1 | TX2 | |
---|---|---|
update emp set sal = 2000 where empno=7788 and sal = 1000; | t1 | |
t2 | update emp set sal = 3000 where empno=7788 and sal = 2000; | |
commit; | t3 | |
t4 | commit; |
상황3
TX1 | TX2 | |
---|---|---|
update t set no = no + 1 where no > 50000; | t1 | |
t2 | insert into t values (1000001,1000001);; | |
t3 | commit; | |
commit; | t4 |
오라클에서 Update 문을 수행하면, 대상 레코드를 읽을 때는 Consistent 모드로 읽고 실제 값을
변경할 ?는 Current 모드로 읽는다 따라서 대상 레코드를 읽기 위한 블록 액세스는 SQL 트레이스에서
Query 항목에서 계산되고, 값을 변경하기 위한 블록 액세스는 Current 항목에서 계산된다.
상황4
TX1 | TX2 | |
---|---|---|
update emp set sal = sal + 100 where empno=7788 and sal = 1000; | t1 | |
t2 | update emp set sal = sal + 200 where empno=7788 and sal = 1000; | |
commit; | t3 | |
t4 | commit; |
① | 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; |
for c in | 모드 |
( | |
select rowid rid from emp | Consistent |
where empno = 7788 and sal = 1000 | |
) | |
loop | |
update emp set sal = sal + 200 | Current |
where empno = 7788 | |
and sal = 1000 | |
and rowid = c.rid; | |
end loop; |
1. select 는 Constistent 모드로 읽는다.
2. insert, update, delete , merge 는 Current 모드로 읽고 쓴다. 다만 갱신할 대상 레코드를 식별하는
작업 만큼은 Consistent으로 이루어진다.
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
TX1 | TX2 | |
---|---|---|
SQL> update 계좌1 set 잔고 = 잔고 + 100 where 계좌번호 = 170; | t1 | |
1 row updated. | t1 | |
SQL> update 계좌2 set 잔고 = 잔고 + 200 where 계좌번호 = 170; | t2 | |
1 row updated. | t2 | |
t3 | SQL> update 계좌2 | |
t3 | set 총잔고 = 계좌2.잔고 + (select 잔고 from 계좌1 where 계좌번호 = 계좌2.계좌번호) | |
t3 | where 계좌번호 = 170; | |
SQL> commit; | t4 | |
t5 | 1 row updated. | |
t5 | SQL> 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
TX1 | TX2 | |
---|---|---|
SQL> update 계좌1 set 잔고 = 잔고 + 100 where 계좌번호 = 170; | t1 | |
1 row updated. | t1 | |
SQL> update 계좌2 set 잔고 = 잔고 + 200 where 계좌번호 = 170; | t2 | |
1 row updated. | t2 | |
t3 | SQL> update 계좌2 | |
t3 | set 총잔고 = (select 계좌2.잔고 + 잔고 from 계좌1 where 계좌번호 = 계좌2.계좌번호) | |
t3 | where 계좌번호 = 170; | |
SQL> commit; | t4 | |
t5 | 1 row updated. | |
t5 | SQL> 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; | Consistent | Current | 쿼리 SCN 이후에 계좌1의 변동 내역이 무시됨 |
update 계좌2 set 총잔고 = (select 계좌2.잔고 + 잔고 from 계좌1 where 계좌번호 = 계좌2.계좌번호) where 계좌번호 = 170; | Current | Current | 계좌1의 현재값을 읽으나, delete 된경우 NULL 로 업데이트 됨 |
스칼라 서브쿼리는 특별한 이유가 없는 항 항상 Consistent 모드로 읽는다