BAD
MAX + 1 방식의 채번
SESSION-A
-- 세션A
-- 데이터 초기화 (두 세션 실행 전에 완료)
TRUNCATE TABLE startdbpg.tr_ord_refund_max;
-- 1
BEGIN;
-- 2 (번호 1 생성, 아직 커밋하지 않음)
INSERT INTO startdbpg.tr_ord_refund_max
(refund_req_no ,ord_no ,refund_amt ,refund_reason ,req_st ,req_dtm)
SELECT COALESCE(MAX(refund_req_no), 0) + 1
,1 ,1000 ,'상품 누락 환불' ,'REQ' ,'2024-01-01'
FROM startdbpg.tr_ord_refund_max;
-- 5 (B가 락 대기 중인 상태에서 커밋)
COMMIT;
SQL
복사
SESSION-B
-- 세션B
-- 3
BEGIN;
-- 4 (동일 번호 1로 INSERT 시도 → 락 대기)
INSERT INTO startdbpg.tr_ord_refund_max
(refund_req_no ,ord_no ,refund_amt ,refund_reason ,req_st ,req_dtm)
SELECT COALESCE(MAX(refund_req_no), 0) + 1
,1 ,1000 ,'상품 누락 환불' ,'REQ' ,'2024-01-01'
FROM startdbpg.tr_ord_refund_max;
-- 6 (A의 COMMIT 후 기본키 중복 오류)
-- 7
ROLLBACK;
SQL
복사
•
MAX + 1 방식은 동시 실행 시 동일한 번호가 생성되어 기본키 충돌로 인한 락 대기와 중복 오류가 발생할 수 있습니다. 특히 트랜잭션이 길어지면 락 대기 시간이 증가해 동시성이 저하됩니다.
GOOD
시퀀스를 이용한 채번
SESSION-A
-- 세션A
-- 데이터 및 시퀀스 초기화 (첫 번째 실행)
TRUNCATE TABLE startdbpg.tr_ord_refund_seq RESTART IDENTITY;
-- 1
BEGIN;
-- 2 (시퀀스로 번호 1 자동 생성)
INSERT INTO startdbpg.tr_ord_refund_seq
(ord_no ,refund_amt ,refund_reason ,req_st ,req_dtm)
VALUES (1 ,1000 ,'상품 누락 환불' ,'REQ' ,'2024-01-01')
RETURNING refund_req_no;
-- 6
COMMIT;
SQL
복사
SESSION-B
-- 세션B
-- 3
BEGIN;
-- 4 (A가 커밋하기 전 번호 2 자동 생성)
INSERT INTO startdbpg.tr_ord_refund_seq
(ord_no ,refund_amt ,refund_reason ,req_st ,req_dtm)
VALUES (1 ,1000 ,'상품 누락 환불' ,'REQ' ,'2024-01-01')
RETURNING refund_req_no;
-- 5 (채번 충돌 없이 정상 커밋)
COMMIT;
SQL
복사
•
BIGSERIAL의 시퀀스를 이용해 번호를 자동 생성하여 동시 실행 시 채번 충돌을 방지합니다.
TIP. 시퀀스를 이용한 자동 채번
•
BIGSERIAL은 시퀀스를 이용해 번호를 자동 생성하는 자료형 선언입니다.
•
시퀀스는 트랜잭션이 롤백되어도 사용한 번호가 복구되지 않으므로 연속된 번호를 보장하지 않습니다.
실행 결과 비교
구분 | BAD — MAX + 1 | GOOD — BIGSERIAL |
SESSION-A 채번 값 | 1 | 1 |
SESSION-B 채번 값 | 1 시도 | 2 |
SESSION-B INSERT | 기본키 충돌로 락 대기 | 정상 처리 |
SESSION-A COMMIT 이후 | SESSION-B 기본키 중복 오류 | 두 세션 모두 정상 커밋 |
두 예제는 각각 해당 테이블을 초기화한 다음 독립적으로 실행합니다. SESSION-A의 초기화 SQL을 먼저 완료하고, 주석의 1~7 또는 1~6 순서로 두 세션을 교대로 실행합니다.
KEY POINT
•
동시 실행 가능성이 있는 채번에 MAX() + 1을 사용하지 않습니다. 시퀀스나 IDENTITY 등 동시성을 고려한 채번 방식을 사용합니다.



