=> PK제약 같은 예외처리를 통하여 동시성 제어(ex : 동시에 Insert 시)
- 번호 할당을 위한 Table -
create table seq_tab (
gubun varchar2(1),
seq number,
constraint pk_seq_tab primary key(gubun, seq)
)organization index;
- 현재의 값에 1을 증가 시켜 사용자에게 리턴하는 Function -
create or replace function seq_nextval(l_gubun number) return number as
/* pragma autonomous_transaction; */
l_new_seq seq_tab.seq%type;
begin
update seq_tab
set seq = seq + 1
where gubun = l_gubun;
select seq into l_new_seq
from seq_tab
where gubun = l_gubun;
commit;
return l_new_seq;
end;
/
- 위의 Table과 Function을 이용하여 채번되는 Transaction -
begin
update tab1
set col1 = :x
where col2 = :y ;
insert into tab2
values (seq_nextval(123), :x, :y, :z);
loop
-- do anything ...
end loop;
commit;
exception
when others then
rollback;
end;
/
# 해결 방안 : "autonomous_transaction" 이용 - Main Transaction과는 별도로 Sub Transaction만 Commit하는 기능 제공
create or replace function seq_nextval(l_gubun number) return number as
l_new_seq seq_tab.seq%type;
begin
.
.
=> 선분이력의 DML(Update, Insert, Delete) 실행으로 발생할 수 있는 동시성 문제(정합성 등) 해결 사례
\- 점이력 : Data의 변경시점만을 관리 => Data + 변경시점
\- 선분이력 : Data의 변경된 시작 시점과 종료시점을 함께 관리 => Data + 시작시점 + 종료시점

- 최종 선분이력을 새로운 선분이력으로 변경하는 Transaction-
declare
cur_dt varchar2(14);
begin
cur_dt := to_char(sysdate, 'yyyymmddhh24miss') ;
update 부가서비스이력
set 종료일시 = to_date(:cur_dt, 'yyyymmddhh24miss') - 1/24/60/60
where 고객ID = 1
and 부가서비스ID = 'A'
and 종료일시 = to_date('99991231235959', 'yyyymmddhh24miss') ;
insert into 부가서비스이력(고객ID, 부가서비스ID, 시작일시, 종료일시)
values (1, 'A', to_date(:cur_dt, 'yyyymmddhh24miss'),
to_date('99991231235959', 'yyyymmddhh24miss')) ;
commit;
end;
# 해결 방안 : 아래의 구문을 Transaction내의 Update 전에 추가
select 고객ID
from 부가서비스이력
where 고객ID = 1
and 종료일시 = to_date('99991231235959', 'yyyymmddhh24miss')
for update nowait ;
select 고객ID
from 고객
where 고객ID = 1
for update nowait ;