하나의 테이블에 여러 트랜잭션에서 일련번호 성 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');
잘된다.