1) Consistent 모드 읽기(gets in consistent mode)
[SQL Trace 결과]
Call Count CPU Time Elapsed Time Disk Query Current Rows
------- ------ -------- ------------ ---------- ---------- ---------- ----------
Parse 1 0.010 0.004 0 0 0 0
Execute 1 0.050 0.042 0 0 0 0
Fetch 3 0.620 0.638 5 6683 0 20
------- ------ -------- ------------ ---------- ---------- ---------- ----------
Total 5 0.680 0.684 5 6683 0 20
[AutoTrace 결과]
Statistics
----------------------------------------------------------
5 recursive calls
30 db block gets
31 consistent gets
0 physical reads
0 redo size
680 bytes sent via SQL*Net to client
625 bytes received via SQL*Net from client
3 SQL*Net roundtrips to/from client
1 sorts (memory)
0 sorts (disk)
14 rows processed
2) Current 모드 읽기(gets in current mode)
<상황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(100001, 100001) | |
t3 | commit; | |
commit; | t4 |
<상황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; |
for c in
( select rowid rid from emp where empno = 7788 and sal = 1000 ) <- Consistent
loop
update emp set sal = sal + 200 where empno = 7788 and sal = 1000 and rowid = c.rid; <- Current
end loop;
단계1] where절에 기술된 조건에 따라 수정/삭제할 대상 레코드의 rowid를 Consistent 모드로 찾는다 (DML 문이 시작된 시점 기준)
단계2] 앞에서 읽은 rowid가 가리키는 레코드를 찾아가 로우 Lock을 설정한 후에 Current 모드로 실제 update/delete를 수행한다.(값이 변경되는 시점 기준)
이 단계에서 Current 모드로 다시 한번 조건을 필터링하고, 갱신할 값을 읽어 수정/삭제한다.
* 단계1을 수행해 대상건을 '모두' 추출하고 나서 단계2를 수행하는것이 아니라, 단계1에서 커서를 열어 Fetch하면서 단계2를 건건히 반복 수행한다.
정리
1. select 는 Consistent 모드로 읽는다.
2. insert, update, delete, merge 는 Current 모드로 읽고 쓴다.
다만, 갱신할 대상 레코드를 식별하는 작업만큼은 Consistent 모드로 이루어 진다.
update 계좌2
set 총잔고 = 계좌2.잔고 +
(select 잔고 from 계좌1 where 계좌번호 = 계좌2.계좌번호)
where 계좌번호 = 7788;
update 계좌2
set 총잔고 = (select 계좌2.잔고 + 잔고 from 계좌1 where 계좌번호 = 계좌2.계좌번호)
where 계좌번호 = 7788;
create table 계좌1
nologging
as
select empno 계좌번호, ename 계좌명, 1000 잔고 from emp;
create table 계좌2
nologging
as
select empno 계좌번호, ename 계좌명, 1000 잔고, 2000 총잔고 from emp;
alter table 계좌1 add constraint 계좌1_pk primary key(계좌번호);
alter table 계좌2 add constraint 계좌2_pk primary key(계좌번호);
select 계좌1.잔고, 계좌2.잔고, 계좌2.총잔고
,계좌1.잔고+계좌2.잔고 총잔고2
from 계좌1, 계좌2
where 계좌1.계좌번호 = 7788
and 계좌2.계좌번호 = 계좌1.계좌번호;
잔고 잔고 총잔고 총잔고2
---------- ---------- ---------- ----------
1000 1000 2000 2000
---------------------- ex 1) ---------------------------------
TX1>
update 계좌1 set 잔고 = 잔고 + 100 where 계좌번호 = 7788;
update 계좌2 set 잔고 = 잔고 + 200 where 계좌번호 = 7788;
TX2>
update 계좌2
set 총잔고 = 계좌2.잔고 +
(select 잔고 from 계좌1 where 계좌번호 = 계좌2.계좌번호)
where 계좌번호 = 7788;
TX1>
commit;
TX2>
commit;
TX1>
select 계좌1.잔고, 계좌2.잔고, 계좌2.총잔고
,계좌1.잔고+계좌2.잔고 총잔고2
from 계좌1, 계좌2
where 계좌1.계좌번호 = 7788
and 계좌2.계좌번호 = 계좌1.계좌번호;
잔고 잔고 총잔고 총잔고2
---------- ---------- ---------- ----------
1100 1200 2200 2300
---------------------- ex 2) ---------------------------------
TX1>
update 계좌1 set 잔고 = 잔고 + 100 where 계좌번호 = 7788;
update 계좌2 set 잔고 = 잔고 + 200 where 계좌번호 = 7788;
TX2>
update 계좌2
set 총잔고 = (select 계좌2.잔고 + 잔고 from 계좌1 where 계좌번호 = 계좌2.계좌번호)
where 계좌번호 = 7788;
TX1>
commit;
TX2>
commit;
TX1>
select 계좌1.잔고, 계좌2.잔고, 계좌2.총잔고
,계좌1.잔고+계좌2.잔고 총잔고2
from 계좌1, 계좌2
where 계좌1.계좌번호 = 7788
and 계좌2.계좌번호 = 계좌1.계좌번호;
잔고 잔고 총잔고 총잔고2
---------- ---------- ---------- ----------
1100 1200 2300 2300