채번 테이블을 이용한 채번(동시성제어)
채번 방법
1) SELECT ~ MAX 방법
. 트랜잭션이 많이 발생하지 않는 트랜잭션에 사용
. 별도의 객체(테이블, 시퀀스, 사용자함수)를 생성 할 필요없어 간단함
. 중복 오류 발생 가능성 있음
. 적절한 인덱스가 없으면 성능 이슈 발생 함
2) 채번 함수 사용(사용자 정의 함수)
. 중복 오류(최초에 발생) 발생 가능성 있음
. 동시성 저하(동시 채번이 발생하면 후행 채번은 선행 세션의 트랜잭션 완료될때까지 대기)
. 관리비용 증가(채번 테이블 추가 생성)
3) 시퀀스 객체 사용
. 차례대로 증가하는 숫자 값을 얻어 낼때 매우 편리
. 트랜잭션의 commit, rollback과 별개로 처리
. NEXTVAL로 시퀀스 값을 발급 받은 후에 ROLLBACK 하면 새로 받은 값은 사라짐
. START WITH n : 시퀀스 시작값 설정
INCREMENT BY n : 시퀀스 증가 값을 설정
MAXVALUE n : 최대값을 설정
MINVALUE n : 최솟값을 설정
CYCLE n | NOCYCLE : 캐시 설정(n만큼 캐시에 시퀀스를 미리 생성)
ORDER | NOORDER : RAC환경에서 시퀀스 정렬 순서 보장 여부
(일반적으로 noorder로 구성하는 것이 좋음)
SELECT ~ MAX 채번은 동시에 여러 사용자가 사용 할 경우
중복 오류가 발생 할 가능성이 크므로 이런 중복 오류를 피하기 위해
채번 함수를 이용한 채번을 사용한다
[ 채번 테이블을 이용한 채번 예제 ]
: 채번 과정을 별도의 트랜잭션으로 처리해 트랜잭션의 동시성을 높임
: tmp_num 테이블에 채번을 처리하고(년도, 구분별로 채번 ) 채번된 값을 리턴한다
CREATE OR REPLACE FUNCTION SF_T_NO
(
v_yyyy char,
v_div char
) return number
IS PRAGMA AUTONOMOUS_TRANSACTION;
// 함수를 호출한 메인 트랜잭션에 영향을 받지 않고 별도의 트랜잭션으로 처리
v_new_no number(6);
BEGIN
// ① 채번 실행
update tmp_num
set no = no + 1
where yy = v_yyyy
and div = v_div ;
// ② 업데이트된게 없으면 최초 채번이므로 insert 수행
if sql%rowcount = 0 then
insert into tmp_num (
yy,
div,
no )
values (
v_yyyy,
v_div,
1 );
end if;
// ③ 채번값 get
select no
into v_new_no
from tmp_num
where yy = v_yyyy
and div = v_div ;
commit ; // ④ 트랜잭션 commit
return v_new_no; // ⑤ 채번 값 return
END;