MySQL은 다른 DBMS와 달리 진정한 의미의 중첩 트랜잭션(nested transaction)을 직접 지원하지 않습니다. 하지만 START TRANSACTION 명령과 SAVEPOINT를 함께 사용하면 마치 중첩된 트랜잭션처럼 동작하도록 만들 수 있습니다. 이 방식을 활용하면 전체 트랜잭션을 롤백하지 않고도 특정 시점으로만 되돌릴 수 있어 데이터 관리가 한층 유연해집니다.
아래 예제를 통해 실제 동작 과정을 단계별로 살펴보겠습니다.
1. 테이블 생성
먼저 CREATE 문을 사용하여 예제에 사용할 테이블을 만듭니다.
mysql> CREATE table transactionDemo -> ( -> id int auto_increment, -> primary key(id) -> ); Query OK, 0 rows affected (0.76 sec)
id 컬럼은 자동 증가(auto_increment) 속성을 가지며 기본 키로 설정되어 있습니다.
2. 트랜잭션 시작
START TRANSACTION 명령으로 새로운 트랜잭션을 시작합니다.
mysql> START TRANSACTION; Query OK, 0 rows affected (0.00 sec)
3. 첫 번째 레코드 삽입 및 저장점 설정
INSERT 문으로 레코드를 하나 추가합니다.
mysql> INSERT into transactionDemo values(); Query OK, 1 row affected (0.04 sec)
SELECT 문으로 현재 저장된 데이터를 확인할 수 있습니다.
mysql> SELECT * from transactionDemo; +----+ | id | +----+ | 1 | +----+ 1 row in set (0.00 sec)
이 상태를 기억시키기 위해 SAVEPOINT를 설정합니다. 저장점 이름은 't2'로 지정했습니다.
mysql> SAVEPOINT t2; Query OK, 0 rows affected (0.00 sec)
4. 두 번째 레코드 삽입
저장점 설정 후 레코드를 하나 더 추가합니다.
mysql> INSERT into transactionDemo values(); Query OK, 1 row affected (0.00 sec)
SELECT 문으로 전체 레코드를 조회하면 두 개의 행이 출력됩니다.
mysql> SELECT * from transactionDemo; +----+ | id | +----+ | 1 | | 2 | +----+ 2 rows in set (0.00 sec)
5. 저장점으로 롤백
이제 ROLLBACK TO 문을 사용하여 't2' 저장점 시점으로 되돌립니다.
mysql> ROLLBACK TO t2; Query OK, 0 rows affected (0.03 sec)
롤백 후 다시 데이터를 조회하면 어떻게 될까요?
mysql> SELECT * from transactionDemo; +----+ | id | +----+ | 1 | +----+ 1 row in set (0.00 sec)
결과 정리
ROLLBACK TO t2 실행 후에는 저장점 이후에 삽입된 두 번째 레코드(id = 2)가 사라지고, 저장점 시점의 첫 번째 레코드(id = 1)만 남게 됩니다.
이처럼 SAVEPOINT를 활용하면 트랜잭션 내부에 논리적인 구분점을 만들어, 전체 작업을 취소하지 않고도 특정 부분만 선택적으로 되돌릴 수 있습니다. 복잡한 비즈니스 로직에서 일부 단계의 실패만 처리하고 싶을 때 매우 유용한 기법입니다.