COMMIT; -- 지금까지의 변경을 확정ROLLBACK; -- 마지막 COMMIT 이후의 변경을 모두 취소SAVEPOINT 이름; -- 중간 저장점 만들기ROLLBACK TO [SAVEPOINT] 이름; -- 저장점 뒤의 변경만 취소
CREATE TABLE T_DEPT AS SELECT * FROM DEPT;INSERT INTO T_DEPT VALUES (50, 'EDUCATION', 'SEOUL');COMMIT;DELETE FROM T_DEPT WHERE DEPTNO = 10;ROLLBACK;SELECT DEPTNO, DNAME FROM T_DEPT ORDER BY DEPTNO;DROP TABLE T_DEPT PURGE;
ROLLBACK 은 COMMIT 이후 전부를 취소한다. 긴 트랜잭션에서 뒤쪽 일부만 취소하려면 중간에 저장점을 찍어 둔다.
CREATE TABLE EMP_T AS SELECT EMPNO, ENAME, SAL FROM EMP WHERE DEPTNO = 10;UPDATE EMP_T SET SAL = 1000 WHERE ENAME = 'CLARK';SAVEPOINT SP1;UPDATE EMP_T SET SAL = 2000 WHERE ENAME = 'KING';SAVEPOINT SP2;DELETE FROM EMP_T WHERE ENAME = 'MILLER';ROLLBACK TO SP2;SELECT ENAME, SAL FROM EMP_T ORDER BY ENAME;ROLLBACK TO SAVEPOINT SP1;SELECT ENAME, SAL FROM EMP_T ORDER BY ENAME;ROLLBACK TO SP2;ROLLBACK;SELECT ENAME, SAL FROM EMP_T ORDER BY ENAME;DROP TABLE EMP_T PURGE;
Table created.1 row updated.Savepoint created.1 row updated.Savepoint created.1 row deleted.Rollback complete.ENAME SAL---------- ----------CLARK 1000KING 2000MILLER 13003 rows selected.Rollback complete.ENAME SAL---------- ----------CLARK 1000KING 5000MILLER 13003 rows selected.ROLLBACK TO SP2*ERROR at line 1:ORA-01086: savepoint 'SP2' never established in this session or is invalidRollback complete.ENAME SAL---------- ----------CLARK 2450KING 5000MILLER 13003 rows selected.Table dropped.
시간 순서로 정리하면 다음과 같다.
CTAS ─ CLARK=1000 ─ [SP1] ─ KING=2000 ─ [SP2] ─ MILLER 삭제 ◀── ROLLBACK TO SP2 : MILLER 복구 ◀────────────────────── ROLLBACK TO SP1 : KING 복구, SP2 소멸 ◀──────────────────────────────────────────── ROLLBACK : CLARK 복구
ROLLBACK TO SP2 는 SP2 뒤의 DELETE 만 취소했다. CLARK·KING 의 변경은 남아 있다.
ROLLBACK TO SP1 뒤에 SP2 로 돌아가려 하자 ORA-01086 이 났다. SP1 보다 뒤에 만든 SP2 는 이미 사라졌기 때문이다.
ROLLBACK TO 는 트랜잭션을 끝내지 않는다. 마지막 ROLLBACK 이 CLARK 의 변경까지 모두 취소했다.
CTAS 는 DDL 이라 그 시점에 커밋되었다. ROLLBACK 해도 EMP_T 자체는 남는다.
CREATE TABLE T_DEPT AS SELECT * FROM DEPT;SAVEPOINT A;DELETE FROM T_DEPT WHERE DEPTNO = 10;SAVEPOINT A;DELETE FROM T_DEPT WHERE DEPTNO = 20;ROLLBACK TO A;SELECT DEPTNO FROM T_DEPT ORDER BY DEPTNO;ROLLBACK;SELECT COUNT(*) FROM T_DEPT;ROLLBACK TO A;DROP TABLE T_DEPT PURGE;
Table created.Savepoint created.1 row deleted.Savepoint created.1 row deleted.Rollback complete. DEPTNO---------- 20 30 403 rows selected.Rollback complete. COUNT(*)---------- 41 row selected.ROLLBACK TO A*ERROR at line 1:ORA-01086: savepoint 'A' never established in this session or is invalidTable dropped.
두 번째 SAVEPOINT A 가 첫 번째 A 를 대신한다. 그래서 ROLLBACK TO A 는 20번 부서만 되살렸다.
ROLLBACK 이나 COMMIT 으로 트랜잭션이 끝나면 저장점도 모두 사라진다. 마지막 ROLLBACK TO A 가 ORA-01086 인 이유다.
⚠️ 함정: 저장점이 여럿일 때 ROLLBACK TO 는 가장 최근 저장점이 아니라 이름을 적은 저장점으로 돌아간다. 그 뒤의 저장점과 변경은 모두 사라지고, 그 앞의 변경은 남는다.
CREATE TABLE T_DEPT AS SELECT * FROM DEPT;INSERT INTO T_DEPT VALUES (50, 'EDUCATION', 'SEOUL');INSERT INTO T_DEPT VALUES (60, 'TOO LONG DEPARTMENT NAME', 'SEOUL');COMMIT;SELECT COUNT(*) FROM T_DEPT;DROP TABLE T_DEPT PURGE;
Table created.1 row created.INSERT INTO T_DEPT VALUES (60, 'TOO LONG DEPARTMENT NAME', 'SEOUL') *ERROR at line 1:ORA-12899: value too large for column "SCOTT"."T_DEPT"."DNAME" (actual: 24, maximum: 14)Commit complete. COUNT(*)---------- 51 row selected.Table dropped.
실패한 INSERT 만 취소되고 앞의 50번 INSERT 는 트랜잭션에 남았다. 이것을 문장 수준 롤백이라 부른다.
오류가 났다고 트랜잭션 전체가 취소되지는 않는다. 이어진 COMMIT 이 50번 행을 확정했다.
BEGIN TRAN;UPDATE ACCOUNT SET BAL = BAL - 100000 WHERE ID = 'A';UPDATE ACCOUNT SET BAL = BAL + 100000 WHERE ID = 'B';COMMIT TRAN; -- 문제가 있으면 ROLLBACK TRAN;
SQL Server 에서도 SET IMPLICIT_TRANSACTIONS ON 을 주면 Oracle 처럼 COMMIT 을 직접 해야 하는 암시적 트랜잭션 모드가 된다.
실습장과 이 노트의 블록은 Oracle 기준이다. SQL*Plus 의 SHOW AUTOCOMMIT 은 실습 컨테이너에서 autocommit OFF 를 보여 줬다.
내일은 테이블을 만들고 고치는 DDL(CREATE·ALTER·DROP)과 제약 조건, 권한을 주고 빼는 DCL(GRANT·REVOKE)을 다룬다.
트랜잭션 : 함께 확정되거나 함께 취소돼야 하는 작업의 묶음. 데이터베이스가 일을 처리하는 논리적 단위다.
TCL : 트랜잭션을 제어하는 명령. COMMIT·ROLLBACK·SAVEPOINT 가 있다.
ACID : 트랜잭션이 지켜야 할 네 성질. 원자성·일관성·고립성·지속성의 머리글자다.
저장점(SAVEPOINT) : 트랜잭션 중간에 찍어 두는 표시. ROLLBACK TO 로 그 지점까지만 되돌린다.
암묵적 COMMIT : 사용자가 COMMIT 을 쓰지 않아도 DDL·DCL 실행이나 정상 종료 때 자동으로 확정되는 것.
AUTO COMMIT : 문장 하나가 끝날 때마다 자동으로 COMMIT 하는 모드. SQL Server 의 기본값이다.
문장 수준 롤백 : 실패한 문장 하나의 변경만 취소하고 같은 트랜잭션의 앞선 변경은 남기는 동작.
📝 연습 문제
선택지를 클릭하면 정답·해설이 펼쳐집니다.
문제 1
EMP_T(CLARK 2450, KING 5000, MILLER 1300)에서 다음을 차례로 실행했다. UPDATE EMP_T SET SAL = 1000 WHERE ENAME = 'CLARK'; → SAVEPOINT SP1; → UPDATE EMP_T SET SAL = 2000 WHERE ENAME = 'KING'; → SAVEPOINT SP2; → DELETE FROM EMP_T WHERE ENAME = 'MILLER'; → ROLLBACK TO SP1; → COMMIT;. 확정된 KING 의 SAL 은?
문제 2
DEPT 를 복사한 T_DEPT(4행)에서 INSERT INTO T_DEPT VALUES (50, 'EDUCATION', 'SEOUL'); → CREATE TABLE T_LOG (MSG VARCHAR2(20)); → ROLLBACK; 을 차례로 실행했다. SELECT COUNT(*) FROM T_DEPT; 의 결과는?
문제 3
"트랜잭션 안의 연산은 모두 반영되거나 하나도 반영되지 않아야 한다"는 성질은?
문제 4
Oracle 과 SQL Server 의 트랜잭션 처리에 대한 설명으로 옳은 것은?
문제 5
DEPT 를 복사한 T_DEPT(10·20·30·40)에서 SAVEPOINT A; → DELETE FROM T_DEPT WHERE DEPTNO = 10; → SAVEPOINT A; → DELETE FROM T_DEPT WHERE DEPTNO = 20; → ROLLBACK TO A; 를 차례로 실행했다. 이때 T_DEPT 의 행 수는?