본문 바로가기

DB/Oracle

[Oracle] Savepoint

1. SAVEPOINT의 이해와 사용

SAVEPOINT는 마치 RPG 게임을 할 때 보스방 앞에서 세이브를 하는 개념과 비슷합니다. 트랜잭션 전체를 롤백하지 않고도 특정한 지점으로 ROLLBACK(롤백)을 할 수 있게끔 임의로 롤백 지점=세이브포인트를 만들어 주는 것이 SAVEPOINT 명령어입니다.

1) SAVEPOINT의 작동

ⓐ 세이브포인트를 표시

ⓑ 세이브포인트 전후로 트랜잭션을 작은 섹션으로 나눈다.

ⓒ 다른 이름의 세이브포인트 여러개를 만들 수 있다.

ⓓ 같은 이름의 세이브포인트를 만들면, 이전의 세이브포인트에 덮어쓰기 된다.

트랜잭션 제어 명령어
기능
COMMIT
보류중인 모든 데이터 변경사항을 영구적으로 적용. 현재 트랜잭션 종료
ROLLBACK
보류중인 모든 데이터 변경사항을 폐기. 현재 트랜잭션 종료, 직전 커밋 직후의 단계로 회귀(되돌아가기)
전체 트랜잭션을 롤백함
SAVEPOINT
ROLLBACK 할 포인트 지정(세이브포인트).
* ANSI 표준SQL이 아님.

2) SAVEPOINT의 사용 방법

(1) 세이브포인트A 만들기

작업중인 지금의 상태를 세이브포인트A로 저장합니다.

ROLLBACK TO SAVEPOINT 시, 현재의 세이브포인트A로 되돌아올 수 있습니다.

savepoint 세이브포인트이름A;

(2) 트랜잭션 수행 중, 세이브포인트A로 돌아가기

트랜잭션 내에서 DML 작업을 진행하던 도중, (모든 트랜잭션을 취소하지 않고) 세이브포인트A로 돌아가고자 할 경우 ROLLBACK TO SAVEPOINT를 사용합니다.

rollback to savepoint 세이브포인트이름A;
 

* 세이브포인트A로 롤백할 경우, 세이브포인트A 이후 시점에 만들어진 다른 세이브포인트들은 삭제됩니다.

이 점은 RPG 게임과 다릅니다.

2. 예제 : SAVEPOINT, ROLLBACK TO SAVEPOINT 사용

※ 예제 과정 : DML작업 → 세이브포인트 생성 → DML 작업 → 세이브포인트로 롤백 → 처음 상태로 롤백

* 이하의 예제에서는 scott 연습계정에서 emp테이블을 복사해 만든 임의의 테이블 emp_t를 사용합니다. 아래의 SQL 쿼리를 실행하여, emp_t 테이블을 만들어 주세요.

create table emp_t as select * from emp;

1) DML 작업 : emp_t 테이블에 임의의 레코드 추가하기

ename이 'ASHIA', 'EGALE' 인 임의의 레코드 2개를 emp_t 테이블에 추가합니다.

insert into emp_t values(8005, 'ASHIA', 'ANALYST', 7782, sysdate, 1000, 100, 10); insert into emp_t values(8006, 'EGALE', 'SALESMAN', 7698, sysdate, 2000, 0, 20);

emp_t 테이블의 13, 14번째에 새로운 행이 추가되었음을 확인하였습니다.

2) 세이브포인트 생성

emp_t 테이블에 'ASHIA', 'EGALE' 레코드가 추가된 현재의 상태를 세이브합니다.

세이브포인트의 이름은 임의로 ashia_egale로 정하였습니다. 아래의 문장을 실행합니다.

savepoint ashia_egale;

'Savepoint이(가) 생성되었습니다' 라는 메시지가 스크립트 출력창에 나타나면, 현재 상태가 세이브된 것입니다.

3) DML 작업 : emp_t 테이블에서 job 변수가 'SALESMAN'인 모든 레코드 삭제하기

emp_t에 DELETE를 사용하여 조건에 맞는 몇 개의 레코드를 삭제합니다.

delete from emp_t where job='SALESMAN';
 

job='SALESMAN'인 레코드 5개가 삭제되었습니다.

4) 세이브포인트로 롤백 :

'ASHIA', 'EGALE' 가 막 추가되었고, 'SALESMAN'인 레코드가 삭제되지 않았을 시점으로 돌아가기

'예제2)'에서 만든 'ashia_egale' 이라는 세이브포인트가 있었습니다. 'SALESMAN' 레코드 5개를 지우기 전으로 돌아가고 싶어서, ROLLBACK TO SAVEPOINT를 사용하여 해당 시점으로 되돌리고자 합니다.

rollback to savepoint ashia_egale;

'롤백 완료'라는 메시지가 나타나면, 정상적으로 해당 세이브포인트 시점으로 돌아간 것입니다.

롤백 결과를 확인하기 위해, emp_t 테이블의 전체 레코드를 조회합니다.

job='SALESMAN'인 5개의 레코드를 삭제하기 전, ename이 'ASHIA'와 'EGALE'인 두 개의 레코드가 막 추가된 시점으로 돌아갔습니다.

5) 롤백 : 트랜잭션이 시작되기 전으로 돌아가기

롤백은 세이브포인트와 상관 없이, 해당 트랜잭션이 시작되기 전(이전 커밋 직후)의 시점으로 돌아가는 명령어입니다. 이 상태에서 롤백을 실행하면:

rollback;

가장 처음의 DML 작업이었던 'ASHIA', 'EGALE' 레코드가 추가되기 이전의 상태로 돌아갔습니다.

지금까지의 과정을 그림으로 나타내면 아래와 같습니다.