2010년 8월 31일 화요일

동시접속 pk 중복 오류 방지방안

하나의 테이블에 여러 트랜잭션에서 일련번호 성 pk 데이타를 입력할 때 중복 오류가 발생하는 현상을 방지할 수 있는 방안입니다.

1. SEQUENCE 오브젝트를 이용한다.

이를 사용하면 일련번호 관련해서 중복오류를 없앨 수 있는 완벽한 방안입니다.

그러나 모델링이나 다른 이슈로 이렇게 처리하지 못하는 경우가 있습니다.

2. 1번에서 문제가 되는 경우가 일련번호가 연도별, 또는 다른 UID별 일련번호 생성과 관련해서일 것이다.

SELECT /*+ INDEX_DESC(A A30_PK) */ nvl(max(일련번호), 0) + 1 as max번호
INTO 일련번호
FROM TABLE_A30 A
WHERE 년도 = 2010

AND ROWNUM = 1;

 

로 MAX값을 구해와야 하는데 ROCK를 걸지 않고 비지니스 로직을 여러곳에서 동시에 실행시에

 

PK중복이 날 수 있다. ( 실제로도 나고 있고 )

 

오라클에서는 이와 같은 문제를 처리하기위해 AUTONOMOUS_TRANSACTION 을 제공한다.

 

CREATE OR REPLACE FUNCTION NUM_VAL (YEAR IN VARCHAR2)
RETURN VARCHAR2
IS
/*********** AUTONOMOUS_TRANSACTION 선언 시작**********/
PRAGMA AUTONOMOUS_TRANSACTION;
/*********** AUTONOMOUS_TRANSACTION 선언 끝**********/

vs_return_val VARCHAR(10);


BEGIN

-- 1. UPDATE --------------
BEGIN
UPDATE TEMP_A
SET SEQ_NO = SEQ_NO + 1
WHERE YEAR = V_YEAR
;
EXCEPTION
WHEN OTHERS THEN
에러처리

END;

-- 2. SELECT --------------
BEGIN
SELECT SEQ_NO
INTO vs_return_val
FROM TEMP_A
WHERE FRM_YEAR = V_YEAR

;
EXCEPTION
WHEN OTHERS THEN
에러처리

END;

COMMIT;
RETURN vs_return_val;

EXCEPTION
WHEN OTHERS THEN
에러처리;
END;

 

 

--SELECT /*+ INDEX_DESC(A A30_PK) */ nvl(max(일련번호), 0) + 1 as max번호
--INTO 일련번호
--FROM TABLE_A30 A
--WHERE 년도 = 2010

--AND ROWNUM = 1;


일련번호 := NUM_VAL('2010');

 

 

잘된다.

 

 

 

 

 

 

댓글 1개:

  1. 안녕하세요 ~
    해당 글 참고해서 function 생성하고 조회 시 ORA-06519 : 자율적인 트랜잭션 사용이 발견도었고 롤백 되었습니다.라는 에러가 발생하네요 ㅠㅠ 혹시 어떻게 수정하면 될 지 알 수 있을까요 ?

    답글삭제