홈 › SQL 실무 › 06 / 9

트랜잭션 기초

COMMIT, ROLLBACK, SAVEPOINT, 자동 커밋, 격리 수준
섹션 6진행 0 / 9

2. 핵심 원리

2.1 트랜잭션이란

트랜잭션은 "전부 반영되거나 전부 취소되는" 문장 묶음입니다. 이 성질을 원자성이라고 하고, 확정한 결과는 사라지지 않는 것을 지속성이라고 합니다. 다른 세션에 언제 얼마나 보이는지는 격리 수준이 정합니다(2.5).

명령 뜻
COMMIT 지금까지의 변경을 확정, 트랜잭션 끝
ROLLBACK 지금까지의 변경을 취소, 트랜잭션 끝
SAVEPOINT 이름 중간 표식, 일부만 되돌리는 데 사용

2.2 시작과 자동 커밋

트랜잭션이 어떻게 시작되는지, 자동 커밋이 기본으로 켜져 있는지가 DB마다 다릅니다.

항목 Oracle · Tibero MySQL MSSQL
시작 첫 DML 에서 암묵 시작 START TRANSACTION 또는 BEGIN BEGIN TRAN
자동 커밋 기본 DB 에는 없음, 도구가 정함 켬 (autocommit=1) 켬 (자동 커밋 모드)
끝 COMMIT, ROLLBACK COMMIT, ROLLBACK COMMIT TRAN, ROLLBACK TRAN

Oracle 은 DB 자체에 자동 커밋이 없고 클라이언트 도구나 드라이버가 정합니다. SQL*Plus 는 기본이 꺼져 있고 JDBC 는 기본이 켜져 있습니다. 같은 Oracle 인데 도구에 따라 결과가 달라지는 이유입니다.

자동 커밋이 켜져 있으면 문장 하나가 끝날 때마다 커밋되어 ROLLBACK 이 되돌릴 것이 없습니다. 여러 문장을 묶으려면 MySQL 은 START TRANSACTION, MSSQL 은 BEGIN TRAN 으로 시작해 자동 커밋을 잠시 멈춥니다. MSSQL 의 IMPLICIT_TRANSACTIONS 옵션을 켜면 Oracle 처럼 첫 DML 에서 자동으로 시작합니다. 기본은 꺼져 있습니다.

핵심

자동 커밋이 켜져 있으면 ROLLBACK 이 소용없습니다. 여러 문장을 묶으려면 트랜잭션을 명시적으로 시작하거나 자동 커밋을 끕니다.

2.3 문장이 실패하면

세 DB 모두 기본은 실패한 문장 하나만 취소되고 트랜잭션은 열려 있습니다. 앞에서 성공한 문장은 그대로 남아 있어서 애플리케이션이 오류를 보고 ROLLBACK 해야 합니다.

MSSQL 은 SET XACT_ABORT ON 이면 대부분의 오류에서 트랜잭션 전체가 롤백됩니다. 켜 두는 것이 안전한 경우가 많지만 모든 오류가 대상은 아니므로 오류 처리를 대신하지는 않습니다.

2.4 SAVEPOINT

SAVEPOINT 는 트랜잭션 안의 중간 표식입니다. 표식 이후만 되돌리고 앞부분과 트랜잭션은 유지합니다. 표식으로 되돌려도 트랜잭션은 끝나지 않아서 마지막에 COMMIT 이나 ROLLBACK 이 필요합니다.

동작 Oracle · Tibero · MySQL MSSQL
표식 만들기 SAVEPOINT s SAVE TRAN s
표식까지 되돌리기 ROLLBACK TO [SAVEPOINT] s ROLLBACK TRAN s

표식보다 뒤에 만든 표식은 그 표식으로 되돌리면 함께 사라집니다. 그래서 sp1 로 되돌린 뒤에는 sp2 로 되돌릴 수 없습니다. H2 는 이 경우 오류 없이 지나가서 소스에는 넣지 않았습니다.

2.5 격리 수준

격리 수준은 동시에 실행되는 다른 트랜잭션의 변경이 내게 언제 보이는지를 정합니다. 표준은 네 단계입니다.

수준 커밋 전 값 읽기 같은 행을 다시 읽을 때 다른 값
READ UNCOMMITTED 읽힘(더티 리드) 가능
READ COMMITTED 안 읽힘 가능
REPEATABLE READ 안 읽힘 안 나옴
SERIALIZABLE 안 읽힘 안 나옴, 순차 실행처럼

DB별 기본값은 다릅니다. 아래 표의 이름은 표준 표기입니다.

DB 기본 격리 수준 비고
Oracle · Tibero READ COMMITTED Oracle 은 READ COMMITTED 와 SERIALIZABLE 만
MySQL InnoDB REPEATABLE READ 표준 4단계 모두
MSSQL READ COMMITTED 기본은 잠금 기반

Oracle 은 읽기를 언두로 일관성 있게 처리해서 읽기가 쓰기를 막지 않습니다. READ UNCOMMITTED 는 Oracle 에 없고, MSSQL 의 WITH (NOLOCK) 은 READ UNCOMMITTED 와 같은 효과입니다. MSSQL 은 기본이 잠금 기반이라 읽기와 쓰기가 서로 기다릴 수 있고, READ_COMMITTED_SNAPSHOT 옵션을 켜면 버전 기반이 됩니다.

주의

커밋하지 않은 채 세션을 오래 두면 그 트랜잭션이 잡은 잠금이 유지되어 다른 세션이 기다립니다. 락 대기와 데드락 상세는 대용량·배치 카테고리에서 다룹니다.