Programming/Oracle

채번 테이블을 이용한 채번(동시성제어)

초록깨비 2022. 1. 17. 16:54
728x90

채번 방법

 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; 

 

 

728x90