Understand Transaction and Control in Database
트랜잭션 이해하고 트랜잭션의 제어 설명

Contents
1️⃣ 트랜잭션 이해하기(Understand Transaction)
2️⃣ 트랜잭션 제어하기(Control Transaction)
1️⃣ 트랜잭션 이해하기(Understand Transaction)
💡Keyword: 원자성(Atomicity), 일관성(Consistency), 격리성(Isolation), 영속성(Durability), 트랜잭션의 시작과 종료, 언두 데이터 세그먼트(Undo Data Segments), 버퍼 캐시(Buffer Cache), V$TRANSACTION
트랜잭션 - 정의 (Definition of Transaction) ⬇️

💡요약: 트랜잭션은 데이터베이스에서 여러 작업을 하나의 단위로 묶어, ALL or NOTHING (모두 성공하거나 아무 것도 적용되지 않음) 방식으로 처리하는 기능이다. 이 방식은 작업 중 일부가 실패했을 때, 데이터 불일치를 방지할 수 있도록 도와준다.
1,000,000원을 계좌 이체하는 상황을 예로 설명하는 위의 예제를 살펴보자.
하나의 명령어는 **저축 계좌(savings_accounts)**에서 1,000,000원을 빼는 것(출금)을 나타낸다.
다른 명령어는 **당좌 계좌(checking_accounts)**에 1,000,000원을 더하는 것(입금)을 나타낸다.
이 두 명령어는 트랜잭션으로 묶여서 동시에 성공해야만 한다. 만약 한쪽 명령어가 실패하면, 다른 쪽도 취소되어야 하므로 출금이나 입금이 모두 실행되지 않게 된다. 이 방식은 작업 중 일부가 실패했을 때, 데이터 불일치를 방지할 수 있도록 도와준다.
트랜잭션 - 예 (Example of Transaction)⬇️

SET TRANSACTION NAME: 트랜잭션의 이름을 지정하는 명령어이다. 여기서는 'bal_update'라는 이름으로 트랜잭션을 시작하고 있다.
UPDATE: 각 계좌에서 잔액을 업데이트하는 명령어이다. **저축 계좌(savings_accounts)**에서 1,000,000원을 빼고, **당좌 계좌(checking_accounts)**에 1,000,000원을 더하는 작업을 수행한다.
COMMIT: 트랜잭션이 성공적으로 완료되었을 때, 이 명령어를 통해 모든 변경 사항을 최종적으로 데이터베이스에 적용한다.
- 트랜잭션에서 중요한 점은 COMMIT 전에 문제가 발생하면 모든 변경 사항이 취소된다는 것이다. 즉, 잔액이 한 계좌에서 빠졌지만 다른 계좌에 들어가지 않은 상황은 발생하지 않게된다.
✅COMMIT 트랜잭션이 성공적으로 완료되면 COMMIT을 통해 데이터를 영구적으로 저장한다. 트랜잭션이 실패할 경우에는 모든 작업이 원래 상태로 돌아가게 된다. 이 과정에선 데이터가 바로 디스크에 쓰여지지 않고, 메모리의 한 부분인 **버퍼 캐시(Buffer Cache)**라는 임시 저장소를 거치게 된다. 참고로 메모리라서 빠르게 읽고 쓸 수 있기 때문에 성능을 높이기 위한 중요한 공간이다. 또한 트랜잭션에서 COMMIT을 사용하는 이유 중 하나가 바로 디스크 I/O를 효율적으로 관리하기 위함이다. 디스크 I/O는 데이터를 디스크에 읽고 쓰는 작업을 말하는데, 이 작업은 시간이 많이 걸리고 시스템 성능에도 영향을 미친다. 그래서 매번 데이터를 디스크에 쓰기보다는, 여러 변경 사항을 한 번에 처리하는 것이 더 효율적이다.
요약하자면 데이터를 매번 디스크에 쓰는 대신, 일단 메모리의 **버퍼 캐시(Buffer Cache)**에 임시로 저장해두고, 여러 작업이 끝난 후에 한 번에 COMMIT을 통해 디스크에 저장한다. 이를 통해 디스크 I/O 작업을 줄일 수 있게 되는 것이다. 만약 데이터 업데이트를 여러 번 시도하는데, 최종 결과가 바뀌지 않으면 변경된 내용을 디스크에 쓰는 것은 낭비라는 점도 생각해 볼만한 관점이다.
트랜잭션 - 트랜잭션이 동작하는 과정 (How transaction process)⬇️
💡요약: 아래의 이미지는 계좌이체 트랜잭션의 예를 통해 트랜잭션이 어떻게 동작하는지 보여준다. 트랜잭션은 데이터베이스에서 안전하게 데이터를 조회하거나 변경하는 과정을 설명하는데, 이때 데이터베이스 서버(Database Server), 데이터파일(Data File), **로그파일(Log File)**이 각각 중요한 역할을 한다.

간단한 예제: A 사용자가 B 계좌로 1,000,000원을 이체하는 과정
A 사용자가 데이터베이스 서버에 변경 요청을 보낸다.
데이터베이스 서버는 A와 B 계좌의 데이터를 데이터파일에서 읽어와 버퍼 캐시에 저장한다.
트랜잭션 중 데이터 변경 사항은 로그파일에 기록된다.
트랜잭션이 성공적으로 완료되면, 데이터는 데이터파일에 저장되고, A 계좌에서 B 계좌로 1,000,000원이 이체된다.
사용자는 이체가 완료되었다는 결과를 받는다.
조회/변경 (Read/Write): 사용자가 조회 요청을 하면, 데이터베이스는 데이터를 읽어와 결과를 사용자에게 반환한다. 변경 요청의 경우, 사용자는 데이터를 업데이트하거나 삭제하는 작업을 수행한다. **조회(Read)**와 변경(Write) 상황에 따라 트랜잭션 처리 과정은 달라진다. 더자세한 설명은 아래 참조
데이터 읽기 (Data Read): 요청된 데이터는 **디스크(Disk)**에 저장되어 있고, 데이터베이스는 디스크에서 데이터를 읽어와 **버퍼 캐시(Buffer Cache)**에 저장한다. 이때, 버퍼 캐시는 메모리에 존재하는 임시 저장소로서 데이터를 빠르게 처리할 수 있게 도와준다.
로그 기록 (Log): 트랜잭션 중 발생한 모든 작업은 **로그파일(Log File)**에 기록된다. 트랜잭션이 실패했을 경우 이 로그를 통해 데이터를 복구할 수 있게 된다.
데이터 쓰기 (Data Write): 트랜잭션이 성공적으로 끝나면, 버퍼 캐시에 있던 데이터가 디스크의 **데이터파일(Data File)**에 최종적으로 저장된다. 이는 데이터를 영구적으로 저장하는 작업이다.
결과 (Result): 트랜잭션이 성공적으로 처리된 후, 결과가 사용자에게 반환된다.
각 구성 요소의 역할
데이터베이스 서버(Database Server): 트랜잭션의 전체 과정을 관리하는 중심 역할을 한다. 사용자가 요청한 데이터 작업을 처리하며, 데이터를 버퍼 캐시에 저장하고 결과를 사용자에게 반환한다.
데이터파일(Data File): 변경된 데이터를 영구적으로 저장하는 장소이다. 최종적으로 트랜잭션이 완료되면, 데이터가 데이터파일에 기록된다.
로그파일(Log File): 트랜잭션 중 일어난 모든 데이터 변경 사항을 기록하는 곳이다. 이는 시스템 장애가 발생했을 때, 데이터를 복구하는 데 중요한 역할을 한다. **검사점(Checkpoint)**을 통해 현재까지의 작업이 완료되었는지 확인할 수 있다.
Checkpoint: **로그파일(Log File)**과 데이터파일(Data File) 간의 **동기화(Synchronization)**를 맞추기 위해 사용되며, 트랜잭션이 진행된 후 주기적으로 변경된 데이터를 버퍼 캐시에서 데이터파일로 기록하는 역할을 한다. 이를 통해 복구 시 로그파일을 모두 읽어들이는 시간을 줄여 복구 속도를 높이고, 시스템 성능을 최적화하는 데 중요한 역할을 한다.

1. 조회 (Read)
조회는 데이터를 읽어오는 작업이다. 조회는 단순히 데이터를 읽어오는 작업이기 때문에 디스크에 데이터를 쓰거나 COMMIT 단계가 필요없다. 또한, 로그파일에 기록할 필요가 없다.
조회 과정:
사용자 요청: 사용자가 데이터 조회 요청을 보낸다. 예를 들어, 특정 사용자의 계좌 잔액을 조회하는 요청을 할 수 있다.
데이터 읽기(Data Read): 데이터베이스 서버는 **데이터파일(Data File)**에서 해당 데이터를 **버퍼 캐시(Buffer Cache)**로 읽어온다. 만약 해당 데이터가 이미 버퍼 캐시에 존재한다면, 바로 캐시에서 데이터를 불러온다.
결과 반환(Result): 데이터베이스 서버가 데이터를 조회한 후, 사용자가 요청한 정보를 반환한다. 조회 작업은 데이터에 변화를 주지 않기 때문에 **로그파일(Log File)**에 기록되지는 않게 된다.
종료: 조회가 완료되면 트랜잭션은 끝나고 사용자는 결과를 받는다.
2. 변경 (Write)
변경 작업은 데이터를 실제로 수정하는 작업이므로, 로그파일에 기록이 필요하고, 트랜잭션이 완료되면 COMMIT을 통해 데이터가 데이터파일에 저장된다. 변경 작업은 조회보다 복잡하고, 데이터 안전성을 보장하기 위한 추가 단계가 필요하다.
변경 과정:
사용자 요청: 사용자가 데이터 변경 요청을 보낸다. 예를 들어, A 계좌에서 B 계좌로 1,000,000원을 이체하는 요청을 할 수 있다.
데이터 읽기(Data Read): 데이터베이스 서버가 데이터를 **버퍼 캐시(Buffer Cache)**로 읽어온다. 이때 필요한 데이터가 버퍼 캐시에 없다면, 데이터파일에서 읽어온다.
로그 기록(Log Write): 데이터베이스 서버는 변경된 데이터에 대한 정보를 **로그파일(Log File)**에 기록한다. 로그는 시스템 장애 발생 시 데이터를 복구하는 데 사용된다. 이 작업은 트랜잭션의 안전성을 위해 매우 중요하다.
데이터 쓰기(Data Write): 트랜잭션이 완료되면, 버퍼 캐시에서 데이터를 **데이터파일(Data File)**에 영구적으로 저장한다. 이 과정은 일반적으로 COMMIT 명령어를 통해 이루어진다.
결과 반환(Result): 데이터 변경이 성공적으로 완료된 후, 사용자는 변경된 결과를 받는다.
결론적으로, 조회는 데이터를 읽어오는 과정만으로 끝나지만, 변경은 데이터를 실제로 수정하고, 트랜잭션의 안정성을 위해 로그 기록과 데이터 쓰기 단계가 추가로 필요하다.
트랜잭션 처리과정 - 오라클 데이터베이스 아키텍쳐⬇️
💡요약: **데이터베이스 버퍼 캐시(Database buffer Cache)**는 데이터를 디스크로 쓰기 전에 메모리에서 임시 저장하여 성능을 최적화한다. **리두 로그 버퍼(Redo log buffer)**는 트랜잭션의 변경 사항을 저장하는 메모리 공간으로, 일정 시점마다 **리두 로그 파일(Redo log file)**에 기록된다. 이를 통해 트랜잭션 복구가 가능하다.
**온라인 리두 로그(Online Redo log)**는 현재 진행 중인 트랜잭션의 변경 사항을 기록하며, **아카이브 리두 로그(Archived Redo log)**는 사용된 온라인 로그를 백업하여 장애 복구 시 사용할 수 있게 한다.
**플래시백 로그(Flashback Log)**는 데이터베이스를 과거의 상태로 복구하는 데 사용된다.

1. 데이터베이스 버퍼 캐시(Database Buffer Cache)의 역할
데이터베이스 버퍼 캐시는 메모리 내에 위치한 공간으로, 디스크에서 읽어온 데이터를 임시로 저장하는 곳이다.
데이터베이스가 디스크에서 데이터를 읽어오거나, 트랜잭션에서 데이터를 변경할 때, 그 변경된 데이터는 먼저 버퍼 캐시에 저장된다.
역할: 이를 통해 데이터베이스는 디스크 I/O를 줄여 성능을 향상시키고, 데이터가 나중에 디스크로 기록되기 전에 메모리 내에서 처리되도록 한다. 따라서 자주 사용되는 데이터를 빠르게 접근할 수 있게 해주는 중요한 역할을 한다.
2. 리두 로그 버퍼(Redo Log Buffer)의 역할과 로그파일과의 관계
**리두 로그 버퍼(Redo Log Buffer)**는 메모리에 위치한 공간으로, 데이터베이스의 변경 사항을 기록하는 역할을 한다. 변경된 데이터는 먼저 버퍼에 저장된 후, 일정 시점이 되면 **리두 로그 파일(Redo Log File)**로 옮겨진다.
로그파일과의 관계: 리두 로그 버퍼에 기록된 내용은 일정 시점마다 **리두 로그파일(Redo Log Files)**에 저장된다. 이는 시스템 장애 발생 시 데이터베이스가 리두 로그파일을 통해 변경된 데이터를 복구할 수 있도록 하기 위함이다. 리두 로그는 데이터를 영구적으로 복구하는 데 핵심적인 역할을 한다.
3. 로그파일이 커질 경우를 대비한 3가지 로그
- 데이터베이스에서 로그파일이 커질 경우 시스템 성능에 영향을 미칠 수 있다. 이를 관리하고 장애 복구 시 유용하게 사용하기 위해 세 가지 종류의 로그가 사용된다.
3.1 온라인 리두 로그(Online Redo Log)
역할: 온라인 리두 로그는 현재 진행 중인 트랜잭션의 변경 사항을 기록하는 로그파일이다. 리두 로그 버퍼에 있는 내용이 주기적으로 이 파일에 저장된다.
트랜잭션이 발생하면, 온라인 리두 로그는 데이터를 기록하여 트랜잭션 완료 전에도 모든 변경 사항이 안전하게 저장될 수 있도록 한다.
특징: 시스템 장애가 발생할 때, 온라인 리두 로그는 가장 최근의 변경 사항을 포함하고 있어 이를 복구하는 데 중요한 역할을 한다.
3.2 아카이브 리두 로그(Archived Redo Log)
역할: 아카이브 리두 로그는 다 사용된 온라인 리두 로그가 차면 자동으로 백업되는 로그파일이다.
이 로그는 시스템 장애 발생 시 데이터베이스가 과거의 데이터 변경 기록을 안전하게 복구할 수 있게 도와준다.
특징: 아카이브 리두 로그는 오래된 로그 기록을 보관하여 트랜잭션의 이전 상태로 되돌릴 수 있는 복구 포인트를 제공한다.
3.3 플래시백 로그(Flashback Log)
역할: **플래시백 로그(Flashback Log)**는 데이터베이스가 과거 시점으로 되돌아갈 수 있도록 도와주는 로그이다.
이 로그는 데이터가 변경되기 이전의 상태를 기록해두고, Flashback 기능을 통해 사용자가 특정 시점으로 데이터베이스를 되돌릴 수 있게 해준다.
특징: 플래시백 로그는 실수로 데이터를 잘못 수정하거나 삭제했을 때, 그 이전 상태로 복구하는 데 유용하다.
트랜잭션 처리과정 - 리두 로그 버퍼 (Redo Log Buffer/File)⬇️

리두 로그는 데이터베이스의 변경 사항을 기록하고, 이를 통해 데이터베이스를 장애 전 상태로 복원할 수 있게 도와주는 중요한 요소이다. 리두 로그 버퍼는 메모리에서 임시로 데이터를 저장하고, 리두 로그 파일은 이를 디스크에 저장하여 데이터를 안전하게 보존한다.
LGWR(Log Writer) 메모리에 있는 로그 데이터를 디스크의 리두 로그 파일로 주기적으로 옮기는 역할을 한다.
간단한 예제:
조회 작업: A 사용자가 B 계좌의 잔액을 조회할 때, 데이터는 변경되지 않으므로 리두 로그에 기록되지 않는다.
변경 작업: A 사용자가 B 계좌로 1,000,000원을 이체할 때, A 계좌의 잔액 감소와 B 계좌의 잔액 증가가 리두 로그 버퍼에 기록되고, 이후 리두 로그 파일에 저장된다. 시스템 장애가 발생해도 이 로그를 통해 트랜잭션을 복구할 수 있게된다.
트랜잭션 특성 - ACID 특성⬇️

트랜잭션 특성 - 원자성(Atomicity)⬇️

원자성(Atomicity)의 정의
트랜잭션은 분리할 수 없는 하나의 단위이다. 즉, 트랜잭션 내에서 수행되는 여러 작업은 개별적으로 수행될 수 없으며, 전체가 하나의 작업처럼 처리된다.
작업이 모두 수행되거나, 하나도 수행되지 않아야 함: 트랜잭션의 모든 작업이 성공적으로 완료되지 않으면, 그 트랜잭션 내에서 이루어진 모든 작업은 취소되어야 한다. 이 과정을 **롤백(Rollback)**이라고 한다.
✅예시: 트랜잭션이 100개의 데이터를 업데이트하려고 시도했으나, 20개의 데이터가 업데이트된 후 시스템 장애가 발생한 상황을 가정해보자
- 이 경우 트랜잭션은 원자성을 보장하기 때문에, 데이터베이스는 이미 변경된 20개의 데이터를 **롤백(Rollback)**하여 트랜잭션이 실행되기 전의 상태로 되돌려야 한다.
트랜잭션 특성 - 일관성(Consistency)⬇️

일관성(Consistency)의 정의
트랜잭션에서 사용되는 모든 데이터는 일관되어야 함: 트랜잭션이 시작되기 전에 데이터는 일관된 상태여야 하며, 트랜잭션이 끝난 후에도 데이터는 여전히 일관성을 유지해야 한다.
트랜잭션의 전후: 트랜잭션이 실행되기 전과 실행된 후에 데이터베이스가 무결한 상태를 유지해야 한다. 즉, 트랜잭션이 완료된 후에도 데이터가 일관성을 유지해야 한다.
✅예시: 계좌 이체 트랜잭션에서 한 계좌만 처리하게 되면 데이터의 일관성이 깨지게 된다.
- 예를 들어, A 계좌에서 1,000,000원이 빠져나갔는데 B 계좌에 그 금액이 입금되지 않으면, 데이터의 일관성이 깨진 것이다. 트랜잭션은 이 문제를 해결해야 하며, 모든 변경 사항이 동시에 완료되거나 모두 취소되어야 일관성을 유지할 수 있게 된다.
트랜잭션 특성 - 격리성(Isolation)⬇️

격리성(Isolation)의 정의
현재 트랜잭션이 접근하고 있는 데이터는 다른 트랜잭션으로부터 격리되어야 함: 한 트랜잭션이 데이터를 변경하는 동안, 그 데이터를 다른 트랜잭션이 수정하거나 읽을 수 없다. 트랜잭션이 완료되기 전까지는 해당 트랜잭션의 중간 결과를 다른 트랜잭션이 보지 못한다.
트랜잭션이 완료되기까지 변경하는 데이터는 다른 트랜잭션에게 보여져서는 안 됨: 트랜잭션이 완료되어야만 그 변경 사항이 다른 트랜잭션에게 공개되며, 트랜잭션 도중에는 서로 격리되어야 데이터의 무결성이 유지된다.
✅예시: : hr.employee 테이블을 업데이트하는 트랜잭션이 실행되는 동안, 다른 트랜잭션이 동일한 테이블에서 수정된 내용을 보지 못한다.
- 즉, 하나의 트랜잭션이 완료되기 전에는 다른 트랜잭션에게 그 결과가 노출되지 않으며, 사용자에게는 트랜잭션이 순서대로 실행되는 것처럼 보여야 한다.
트랜잭션 특성 - 영속성(Durability)⬇️

영속성(Durability)의 정의
트랜잭션이 정상적으로 종료되면 그 결과는 시스템 오류가 발생하더라도 영구적으로 남아야 함: 즉, 트랜잭션이 완료되고 **커밋(Commit)**이 되면, 그 결과는 시스템 장애나 오류가 발생해도 데이터베이스에 안전하게 저장된다.
혹시 완료된 데이터에 장애가 생기면 이를 다시 복구할 수 있어야 함: 트랜잭션이 완료된 후 장애가 발생해도 데이터는 복구 가능해야 하며, 트랜잭션의 변경 사항은 디스크에 안전하게 저장되어야 한다.
✅예시: 계좌 이체 트랜잭션에서 데이터가 로그에 기록되고 **커밋(Commit)**이 된 후, 시스템 장애가 발생해도, 시스템이 다시 재가동되었을 때 해당 변경 사항은 디스크에 반영되어 있어야 한다. 즉 계좌 이체가 완료된 후 서버가 다운되더라도, 이체된 금액은 영구적으로 반영되어야 한다.
트랜잭션 구조 - 트랜잭션은 하나 또는 그 이상의 명령문으로 구성됨⬇️
💡요약: 트랜잭션은 하나 이상의 명령문으로 구성될 수 있으며, 이 명령문들은 데이터 조작문(DML) 또는 **데이터 정의문(DDL)**으로 이루어진다. 각 명령문은 함께 실행되어 데이터베이스의 무결성과 일관성을 유지할 수 있도록 도와준다.
하나 또는 그 이상의 명령문으로 트랜잭션이 구성될 수 있다. 트랜잭션은 여러 개의 작업을 하나의 단위로 묶어 처리하기 때문에, 모든 명령문이 함께 실행되어야 한다.
트랜잭션은 주로 데이터 조작문(DML, Data Manipulation Language) 또는 **데이터 정의문(DDL, Data Definition Language)**으로 이루어져 있다.
데이터 조작문 (DML, Data Manipulation Language)
**데이터 조작문(DML)**은 데이터를 조회, 추가, 수정, 삭제하는 명령어들로 구성된다.
조회(Read): 데이터를 단순히 읽어오는 작업으로, DML의
SELECT문을 사용한다.변경(Write): 데이터에 변화를 주는 작업으로,
INSERT(데이터 추가),UPDATE(데이터 수정),DELETE(데이터 삭제)와 같은 명령어가 포함된다.DML 명령문은 트랜잭션 안에서 여러 개가 함께 실행될 수 있으며, 모두 성공해야만 데이터베이스에 최종 적용된다.
DML 예시:
A 사용자가 B 계좌의 잔액을 조회하는 경우:
SELECT balance FROM accounts WHERE account_id = BA 사용자가 B 계좌에 1,000,000원을 추가하는 경우:
UPDATE accounts SET balance = balance + 1000000 WHERE account_id = B
데이터 정의문 (DDL, Data Definition Language)
**데이터 정의문(DDL)**은 데이터베이스 구조를 정의하는 명령어들이다.
예를 들어, 새로운 테이블을 생성하거나, 기존 테이블을 수정 또는 삭제하는 작업을 포한다.
DDL 명령문에는
CREATE(테이블 생성),ALTER(테이블 구조 변경),DROP(테이블 삭제) 등이 있다.DDL은 트랜잭션처럼 사용되며, 명령문이 성공적으로 완료되면 데이터베이스 구조가 바뀐다.
DDL 예시:
새로운
employees테이블을 생성하는 경우:CREATE TABLE employees (id INT, name VARCHAR(50), position VARCHAR(50))기존
employees테이블에salary컬럼을 추가하는 경우:ALTER TABLE employees ADD salary INT
트랜잭션 구조 - 트랜잭션의 시작⬇️
💡요약: 트랜잭션의 시작에 대해 알아본다. 트랜잭션은 데이터베이스에서 여러 작업을 하나의 단위로 묶어 처리하는데, 그 시작 과정에서 몇 가지 중요한 단계가 있다. 좀 더 자세히 살펴보면 트랜잭션은 첫 SQL 문이 실행되면 자동으로 시작되며, 이 과정에서 데이터베이스는 트랜잭션을 추적하고 롤백할 수 있도록 언두 데이터 세그먼트를 확보한다. 또한, 트랜잭션에 고유한 ID가 부여되며, 이를 통해 트랜잭션 상태를 V$TRANSACTION 뷰에서 확인할 수 있게 된다.
첫 번째 SQL 문이 시작되면 트랜잭션이 자동으로 시작된다.
- 트랜잭션은 사용자가 처음으로 SQL 문(예:
SELECT,INSERT,UPDATE,DELETE)을 실행하면 자동으로 시작된다. 특별히 트랜잭션을 시작하라는 명령을 내리지 않아도, 첫 SQL 문이 실행되면서 트랜잭션이 시작된다.
- 트랜잭션은 사용자가 처음으로 SQL 문(예:
트랜잭션 안에서 DML, DDL, SET TRANSACTION 문을 사용할 수 있다.
트랜잭션 안에서 사용할 수 있는 명령문은 DML(Data Manipulation Language), DDL(Data Definition Language), 그리고 트랜잭션의 특성을 설정할 수 있는 SET TRANSACTION 문이다.
DML은 데이터를 조회하거나 수정하는 데 사용되고, DDL은 데이터베이스 구조를 정의하거나 변경하는 데 사용된다.
언두 데이터 세그먼트(Undo Data Segments) 확보하여 롤백 지원
트랜잭션이 시작되면, 데이터베이스는 **언두 데이터 세그먼트(Undo Data Segments)**를 확보한다. 이는 트랜잭션이 완료되기 전에 데이터가 변경되었을 경우, 이전 상태로 되돌리기 위한 정보를 저장하는 공간이다.
언두 세그먼트는 트랜잭션 도중 문제가 발생하면 **롤백(Rollback)**을 통해 데이터베이스를 트랜잭션 이전 상태로 복구할 수 있도록 도와다.
트랜잭션 ID 부여 후 정보 삽입
- 데이터베이스는 각 트랜잭션에 고유한 트랜잭션 ID를 부여하고, 이 ID와 관련된 정보를 트랜잭션 테이블에 저장하게 된다. 이 고유 ID는 트랜잭션을 추적하고 관리하는 데 사용된다.
V$TRANSACTION 뷰를 통해 트랜잭션 상태 확인 가능
- 데이터베이스는 V$TRANSACTION 뷰를 통해 현재 진행 중인 트랜잭션의 상태를 확인할 수 있게 한다. 이를 통해 사용자는 각 트랜잭션이 어떤 상태에 있는지(예: 진행 중, 커밋됨, 롤백됨)를 실시간으로 확인할 수 있다.
간단한 예제:
사용자가
UPDATE문을 실행하여 A 계좌의 잔액을 1,000,000원 감소시키는 경우트랜잭션 시작:
UPDATE문이 처음 실행되면서 트랜잭션이 자동으로 시작된다.언두 데이터 세그먼트 확보: A 계좌의 원래 잔액 정보가 언두 세그먼트에 저장되어, 필요 시 롤백이 가능하게 한다.
트랜잭션 ID 생성: 이 트랜잭션에 고유한 ID가 부여되고, 트랜잭션 테이블에 기록된다.
상태 확인: 사용자는 V$TRANSACTION 뷰를 통해 트랜잭션 상태를 확인할 수 있다.
✅언두 데이터 세그먼트(Undo Data Segments): 언두 데이터 세그먼트는 트랜잭션이 변경한 데이터의 이전 상태를 저장하는 공간이다. 만약 트랜잭션 도중 오류가 발생해 롤백이 필요할 때, 언두 데이터 세그먼트에 저장된 정보를 사용하여 데이터베이스를 트랜잭션 이전 상태로 복구할 수 있게 된다. 예를 들어, 계좌 이체 트랜잭션에서 A 계좌에서 돈이 빠져나간 후 트랜잭션이 중단되면, 언두 데이터 세그먼트를 사용하여 A 계좌의 잔액을 원래대로 되돌릴 수 있게 된다.
✅언두 데이터 세그먼트(Undo Data Segments)와 버퍼 캐시(Buffer Cache)의 관계: 언두 데이터 세그먼트의 내용도 버퍼 캐시에 저장된다. 즉, 트랜잭션이 데이터를 변경하면 그 변경된 데이터와 함께 언두 데이터(이전 데이터)도 버퍼 캐시에 올라가게 된다. 이는 롤백 시 빠르게 데이터를 복구할 수 있도록 하기 위함이다. 또한 트랜잭션이 진행 중일 때, 버퍼 캐시에는 변경된 데이터뿐 아니라 언두 데이터도 함께 저장되어 있어야 한다. 이로 인해 트랜잭션이 도중에 실패하면, 버퍼 캐시의 언두 데이터를 활용해 데이터베이스를 트랜잭션 이전 상태로 되돌릴 수 있게 된다. 트랜잭션 중 문제가 발생하여 **롤백(Rollback)**이 필요할 때, 언두 데이터는 버퍼 캐시와 디스크의 언두 세그먼트에서 참조되어 데이터를 원래 상태로 복구할 수 있다.
간단한 예제:
A 사용자가 B 계좌로 1,000,000원을 이체하는 트랜잭션이 시작되면:
A 계좌의 잔액 감소와 B 계좌의 잔액 증가가 버퍼 캐시에 저장된다.
동시에, A 계좌와 B 계좌의 잔액 원본 데이터가 언두 데이터 세그먼트에 저장되고, 이는 버퍼 캐시에도 올라간다.
만약 트랜잭션 도중 오류가 발생하면:
- 버퍼 캐시에 있는 언두 데이터가 사용되어, A와 B 계좌의 잔액이 원래대로 복구된다.
트랜잭션 구조 - 트랜잭션의 시작⬇️

테이블 생성 (Creating a Table):
CREATE TABLE temp_table문을 통해 temp_table이라는 이름의 테이블이 생성되었다. 이 테이블에는 user_id(정수형)와 user_name(문자열형) 두 개의 열(column)이 포함되어 있다.이 단계는 데이터베이스에 테이블 구조를 정의하는 DDL(Data Definition Language) 명령이다.
데이터 삽입 (Inserting Data):
INSERT INTO temp_table VALUES (1000, '강하나');문을 통해 temp_table에 user_id가 1000이고 **user_name이 '강하나'**인 행(row)을 삽입한다.이 단계는 DML(Data Manipulation Language) 명령이며, 데이터가 실제로 테이블에 추가된다.
이 명령이 실행되면서 트랜잭션이 자동으로 시작된다.
트랜잭션 상태 확인 (Checking Transaction Status):
SELECT * FROM V$TRANSACTION;명령을 통해 현재 진행 중인 트랜잭션의 상태를 확인한다.V$TRANSACTION 뷰를 사용하여 트랜잭션의 고유 ID, 상태, 시작 시간 등을 확인할 수 있다. 여기서
STATUS열에 ACTIVE라고 표시된 것은 이 트랜잭션이 아직 진행 중임을 의미한다.
커밋 (Commit):
COMMIT;문을 실행하면 트랜잭션이 완료되며, 변경 사항이 데이터베이스에 영구적으로 저장된다.커밋이 완료되면 트랜잭션은 더 이상 ACTIVE 상태가 아니며, 다른 사용자에게도 데이터 변경 사항이 보이게 된다.
트랜잭션 구조 - 트랜잭션이 종료되는 경우#1⬇️
💡요약: 트랜잭션은 명시적으로 COMMIT 또는 ROLLBACK 명령어를 실행하거나, DDL 명령어를 사용해 데이터베이스 구조를 정의 또는 변경할 때 자동으로 종료된다. 이를 통해 트랜잭션의 상태를 명확하게 관리할 수 있게 된다.
명시적으로 COMMIT 또는 ROLLBACK 문을 실행시키는 경우
사용자가 직접 COMMIT 또는 ROLLBACK 명령을 실행하면, 트랜잭션이 종료된다.
COMMIT은 트랜잭션에서 이루어진 모든 변경 사항을 영구적으로 데이터베이스에 저장하며, ROLLBACK은 모든 변경 사항을 취소하고 원래 상태로 되돌린다.
DDL 명령어를 실행시키는 경우
DDL(Data Definition Language) 명령어는 데이터베이스 구조를 정의하거나 변경하는 명령어로, 여기에는
CREATE,DROP,RENAME,ALTER와 같은 명령어가 포함된다.DDL 명령어를 실행할 때마다 해당 명령어 전후로 자동으로 COMMIT이 실행되어 트랜잭션이 종료된다. 즉, DDL 명령어는 자동으로 트랜잭션을 종료시키는 역할을 한다.
예를 들어,
CREATE TABLE명령을 사용해 테이블을 생성하면 그 명령어가 실행되기 전에 현재 트랜잭션이 자동으로 커밋되고, 명령이 완료된 후에도 자동으로 커밋된다.사용자가 SQL 도구(예: SQL Plus, SQL Developer 등)를 정상적으로 종료하면, 현재 트랜잭션도 자동으로 COMMIT될 수 있다. 프로그램에 따라 다를 수 있지만, 대부분의 도구에서 정상 종료 시 자동 커밋이 이루어진다.
만약 비정상적으로 프로그램이 종료되면, 현재 트랜잭션은 자동으로 ROLLBACK된다.
2️⃣ 트랜잭션 제어하기(Control Transaction)
💡Keyword: Commit, Rollback, Save Point, Concurrency Control, Lock
💡요약: 트랜잭션 제어는 데이터베이스의 일관성을 보장하며, 데이터 수정이 올바르게 수행될 수 있도록 돕는다.
트랜잭션 제어란 데이터베이스에서 트랜잭션(Transaction)을 관리하는 것을 의미한다.
트랜잭션이란 데이터베이스에서 실행되는 작업의 묶음으로, 여러 DML(Data Manipulation Language) 문장이 포함된다. 트랜잭션 제어는 데이터의 일관성을 유지하기 위해 중요한 역할을 한다. 예를 들어, 은행에서 계좌 이체를 할 때, 송금과 입금 과정이 둘 다 완료되어야 일관성이 유지된다. 트랜잭션 제어는 이러한 작업이 완전히 이루어졌는지 확인하고, 문제가 생기면 롤백(rollback)하여 원래 상태로 되돌리는 기능도 포함한다.
트랜잭션 제어문(Transaction Control Statement)
💡요약: 트랜잭션 제어문은 데이터베이스의 변경 사항을 영구적으로 저장하거나, 오류가 발생했을 때 안전하게 이전 상태로 되돌리기 위한 도구로 COMMIT, ROLLBACK, ROLLBACK TO SAVEPOINT, SAVEPOINT 등이 제어문에 포함된다.
COMMIT: 현재 트랜잭션을 종료하고 변경된 사항을 영구적으로 유지(permanently save)한다. 이를 통해 데이터베이스에 디스크로 반영되어 수정된 데이터가 확정된다. SAVEPOINT(임시 저장 지점)를 제거하고, LOCK(잠금)을 해제한다.
- 예: 은행에서 돈을 이체할 때, 이체가 끝난 후 COMMIT을 사용하면 송금이 완료된다.
ROLLBACK: 현재 트랜잭션에서 이루어진 모든 작업을 되돌린다. (undo all changes). 문제가 발생했을 때, 트랜잭션을 원래 상태로 되돌리기 위해 사용된다.
- 예: 은행 이체 중에 에러가 발생하면 ROLLBACK을 사용하여 모든 작업을 취소하고 처음 상태로 돌아간다.
ROLLBACK TO SAVEPOINT: 마지막으로 설정한 SAVEPOINT 이후에 진행된 작업만 되돌린다.(undo changes after the last save point). 부분적으로 되돌릴 때 유용하다.
- 예: 여러 단계의 데이터 수정 작업 중 오류가 발생하면, SAVEPOINT를 지정한 지점까지 되돌릴 수 있다.
SAVEPOINT: 트랜잭션이 진행되는 중간에 ROLLBACK할 지점을 저장(set a temporary save point)한다. 트랜잭션 중 특정 지점까지 되돌릴 수 있도록 한다.
- 예: 장바구니에 여러 물건을 추가하다가, 특정 지점(SAVEPOINT)을 설정해두고 이후에 되돌리고 싶을 때 사용한다.
트랜잭션 이름(Transaction Name)
💡요약: 트랜잭션 이름을 설정하면, 긴 트랜잭션을 쉽게 관리하고, 문제가 발생했을 때 빠르게 찾아 복구하는 데 도움이 된다. 간략한 특징으로는 트랜잭션 이름은 선택 사항이고 트랜잭션 종료 시 로그에 기록되어 나중에 쉽게 검색이 가능해진다.
SET TRANSACTION ... NAME
트랜잭션 명은 선택사항이며, 필요할 때 특정 트랜잭션을 지정하기 위해 사용한다.
- 예: 여러 작업 중 하나의 트랜잭션을 구분하고 싶다면,
SET TRANSACTION ... NAME명령어로 트랜잭션에 이름을 지정할 수 있다.
- 예: 여러 작업 중 하나의 트랜잭션을 구분하고 싶다면,
길게 수행되는 트랜잭션의 모니터링을 편하게 한다. 이름을 지정하면 어떤 트랜잭션이 오래 걸리는지 파악하기 쉽다.
- 예: 트랜잭션에 이름을 붙여두면, 어떤 작업이 느리게 진행되는지 쉽게 모니터링할 수 있게 된다.
V$TRANSACTION 뷰 등에서 트랜잭션을 쉽게 검색할 수 있다. 트랜잭션 이름을 통해 시스템 사전에서 특정 트랜잭션을 찾아 관리할 수 있다.
- 예: 데이터베이스 관리자가 V$TRANSACTION 뷰에서 이름을 검색해 트랜잭션을 추적할 수 있다.
Redo Log에 트랜잭션 종료 시 기록되어, 나중에 쉽게 검색할 수 있다. Redo Log는 데이터베이스 복구 시 유용하며, 트랜잭션 이름이 기록되면 이를 통해 빠르게 찾을 수 있게한다.
- 예: 데이터 복구 작업을 할 때, 특정 트랜잭션 이름을 통해 필요한 로그를 쉽게 찾을 수 있게한다.
트랜잭션 코밋(Commit)
💡요약: 커밋은 트랜잭션의 변경 사항을 영구적으로 반영하며, 데이터를 변경할 때 중요한 과정이다. 커밋이 완료되면, 변경 사항이 디스크에 반영되고 다른 사용자도 변경된 데이터를 볼 수 있게된다.
Undo data 생성: 변경 전 데이터 보존.
Redo 로그 생성: 트랜잭션의 변경 사항 기록.
LOCK 해제: 트랜잭션 완료 시 잠금 해제.
COMMIT의 과정을 살펴보자
DBMS는 SGA에 undo data 정보를 생성: Undo data는 데이터가 변경되기 전의 값을 저장한다. 이렇게 하면 필요할 때 이전 상태로 되돌릴 수 있게 된다.
- 예: 한 고객의 계좌 잔액을 수정하기 전에, 원래 잔액 정보를 undo data에 저장
⬇️
- undo data는 변경되기 전의 데이터 값을 가짐: 변경이 되기 전의 데이터 값을 보존하여 문제가 발생했을 때 쉽게 복구할 수 있게 한다.
⬇️
- SGA의 온라인 로그 버퍼에 redo 로그를 생성: Redo 로그는 트랜잭션의 변경 내용을 기록한다. 이는 데이터베이스가 예기치 않게 종료될 경우 데이터를 복구하는 데 사용된다.
⬇️
- redo 로그는 데이터 블록의 변경 사항과 undo 블록의 변경 사항을 기록: 트랜잭션에서 변경된 데이터와 그에 대한 복구 정보를 함께 저장한다.
⬇️
- SGA의 데이터베이스 버퍼를 변경: 실제로 데이터베이스에 반영하기 위해 버퍼의 내용을 업데이트한다.
⬇️
- DBW(database writer)는 데이터베이스 버퍼의 내용을 디스크에 주기적으로 반영: 변경된 데이터가 일정 주기마다 디스크에 저장된다. 이는 데이터를 영구적으로 보존하기 위함이다.
⬇️
변경이 이루어진 로우는 LOCK이 걸림
- 트랜잭션이 끝나면 LOCK(잠금)이 해제된다. 이는 다른 사용자가 동일한 데이터를 동시에 수정하지 못하게 하여 데이터 일관성을 유지하는 역할을 한다.
롤백과 트랜잭션 대기 - 세이브포인트(Savepoint)
💡요약: 세이브포인트는 긴 트랜잭션 중 일부만 되돌리고 싶을 때 유용하게 사용할 수 있다.
Savepoint: 트랜잭션 중 특정 지점 저장.
Rollback to Savepoint: 지정한 지점 이후의 변경 사항만 되돌림.
전체 롤백이 아님: 트랜잭션의 일부만 취소 가능.
세이브포인트는 사용자가 트랜잭션 중간에 특정 지점을 표시: Savepoint는 트랜잭션 중간에 임시 저장 지점을 설정하는 기능이다. 이를 통해 나중에 해당 지점으로 되돌아갈 수 있게 한다.
- 예: 쇼핑몰에서 여러 제품을 장바구니에 담고, 한 번에 구매를 결정하기 전에 세이브포인트를 설정하여 변경을 쉽게 되돌릴 수 있다.
Rollback to Savepoint는 지정한 세이브포인트 이후로 변경이 없도록 복구: 이를 사용하면 설정한 세이브포인트 이후에 이루어진 변경 사항만 되돌린다. 전체 트랜잭션을 취소하는 것이 아닌 부분적인 취소가 가능하다.
- 예: 예를 들어 SAVEPOINT A를 설정하고 B와 C 작업을 했다면, Rollback to Savepoint A를 하면 B와 C 작업만 취소된다.
트랜잭션 자체의 롤백은 아님: Savepoint와 Rollback to Savepoint는 전체 트랜잭션을 되돌리는 것이 아니며, 특정 지점 이후의 변경만 되돌린다.
예제
ROLLBACK TO SAVEPOINT after_banda_sal;
위 명령어는 after_banda_sal이라는 세이브포인트 이후의 작업만 되돌리게 한다. 이때 after_banda_sal 이전에 생성한 다른 SAVEPOINT는 그대로 유지되지만, 그 이후에 만들어진 SAVEPOINT는 사라지게 된다.
롤백과 트랜잭션 대기 - 실행 예제 #1
💡요약: 트랜잭션 내에서 데이터를 변경하고, 특정 지점까지 롤백할 수 있는 SAVEPOINT를 설정하는 방법이다. 이를 통해 부분적인 변경만 되돌릴 수 있어 데이터 관리에 유연성을 제공한다.
COMMIT: 이전 트랜잭션 종료 및 변경 사항 영구 저장.
SET TRANSACTION NAME: 트랜잭션 이름 지정으로 관리 용이.
UPDATE: 특정 직원의 급여 수정.
SAVEPOINT: 트랜잭션 중간에 임시 저장 지점 설정.
t0 - COMMIT
- COMMIT 명령어는 현재 세션에 있는 기존 트랜잭션을 종료하고, 이전에 이루어진 모든 변경 사항을 영구적으로 저장한다.
t1 - SET TRANSACTION NAME 'sal_update'
- 트랜잭션을 시작하고 이름을 sal_update로 지정한다. 트랜잭션 이름을 지정하면 나중에 이 트랜잭션을 쉽게 관리하고 모니터링할 수 있게된다.
t2 - UPDATE employees SET salary = 7000 WHERE last_name = 'Banda'
- 직원 테이블에서 last_name이 Banda인 사람의 salary를 7000으로 업데이트한다. 이 명령어는 특정 직원의 급여를 수정하는 예다.
t3 - SAVEPOINT after_banda_sal
- after_banda_sal이라는 SAVEPOINT를 생성한다. 이제 트랜잭션을 되돌릴 때 이 지점까지 되돌릴 수 있게 된다. 예를 들어 이후에 오류가 발생하면 after_banda_sal 지점으로 복구할 수 있다.
t4 - UPDATE employees SET salary = 12000 WHERE last_name = 'Greene'
- 직원 테이블에서 last_name이 Greene인 사람의 salary를 12000으로 업데이트한다. 이 명령어는 다른 직원의 급여를 수정하는 예이다.
롤백과 트랜잭션 대기 - 실행 예제 #2
💡요약: 아래 예제는 여러 SAVEPOINT를 설정하고 롤백을 통해 특정 지점으로 되돌리는 추가적인 방법을 보여준다. 또한 전체 트랜잭션을 롤백하여 모든 변경 사항을 취소하고, 새로운 트랜잭션을 시작하는 과정도 설명한다. 이를 통해 데이터의 일관성을 유지하면서 변경을 관리하는 방법을 이해할 수 있게 된다.
SAVEPOINT: 트랜잭션 중간에 지정 지점 생성 (롤백 기준).
ROLLBACK TO SAVEPOINT: 특정 SAVEPOINT 이후 변경 사항 되돌림.
ROLLBACK: 트랜잭션의 모든 변경 사항 되돌리고 종료.
SET TRANSACTION NAME: 새로운 트랜잭션 시작 및 이름 지정.
t5 - SAVEPOINT after_greene_sal
after_greene_sal이라는 SAVEPOINT를 설정한다. 이는 트랜잭션의 중간 지점으로, 이후 변경 사항을 롤백할 수 있는 기준점이 된다.
이 SAVEPOINT를 통해 Greene의 급여 변경 작업 이후로 돌아갈 수 있게 된다.
t6 - ROLLBACK TO SAVEPOINT after_banda_sal
after_banda_sal이라는 SAVEPOINT로 롤백한다. 이 명령어는 트랜잭션을 t3 단계로 되돌려서 t4에서 수행된 Greene의 급여 업데이트를 취소하게 된다.
트랜잭션은 종료되지 않았으며, 롤백만 실행되었다.
t7 - UPDATE employees SET salary = 11000 WHERE last_name = 'Greene'
- Greene의 salary를 11000으로 업데이트한다. 이전에 롤백된 salary 값을 새롭게 설정하는 단계이다.
t8 - ROLLBACK
- 이 명령어는 현재 sal_update 트랜잭션의 모든 변경 사항을 되돌리고 트랜잭션을 종료한다. Greene와 Banda의 급여 업데이트가 모두 취소된다.
t9 - SET TRANSACTION NAME 'sal_update2'
- 새로운 트랜잭션을 시작하고 sal_update2라는 이름을 지정한다. 이전 트랜잭션이 롤백으로 종료되었기 때문에 새로운 트랜잭션이 시작되게 된다.
롤백과 트랜잭션 대기 - 트랜잭션 대기(Waiting) #1
💡요약: 새로운 트랜잭션 sal_update2에서 이루어진 데이터 변경을 완료하는 과정을 살펴보자 트랜잭션에서 수행된 모든 변경 사항을 COMMIT으로 영구 저장하여 완료하는 과정이다.
UPDATE: 특정 직원의 급여 업데이트.
COMMIT: 트랜잭션 종료 및 모든 변경 사항 영구 저장.
t10 - UPDATE employees SET salary = 7050 WHERE last_name = 'Banda'
- Banda의 salary를 7050으로 업데이트한다. 새로운 트랜잭션 sal_update2에서 진행되는 변경 작업 중 하나이다.
t11 - UPDATE employees SET salary = 10950 WHERE last_name = 'Greene'
- Greene의 salary를 10950으로 업데이트한다. 이 역시 sal_update2 트랜잭션 내에서 수행된 변경 작업이다.
t12 - COMMIT
- sal_update2 트랜잭션의 모든 변경 사항을 COMMIT한다. 이를 통해 Banda와 Greene의 급여 업데이트가 영구적으로 저장된다. COMMIT 명령어는 변경 사항을 online redo log files에 기록하여 데이터베이스에 확정적으로 반영되도록 보장한다.
롤백과 트랜잭션 대기 - 트랜잭션 대기(Waiting) #2
💡요약: 트랜잭션 대기 상황은 데이터베이스에서 자원의 충돌을 방지하고 데이터 일관성을 유지하는 중요한 역할을 한다.
트랜잭션 대기 (Waiting): 하나의 자원을 동시에 접근하려고 할 때, 나중에 실행된 트랜잭션은 잠금이 해제될 때까지 기다림.
Commit: 첫 번째 세션에서 Commit을 완료하면 두 번째 세션이 대기 상태에서 벗어나 작업을 수행.

- 트랜잭션 대기 (Waiting) 상황을 보여주는 예제이다. 하나의 트랜잭션이 특정 자원을 사용하고 있을 때, 다른 트랜잭션이 해당 자원을 사용하기 위해 대기해야 하는 상황이다. 즉 나중에 실행된 트랜잭션은 해당 자원의 락이 해제 될 때까지 기다려야한다. 이러한 트랜잭션 대기는 데이터 일관성을 유지하고 충돌을 방지하기 위해 필수적이다.
롤백과 트랜잭션 대기 - 트랜잭션 대기(Waiting) #3

- 첫 번째 세션에서 Banda의 급여를 7000으로 업데이트하고 SELECT문을 통해 결과를 조회하였다. 이 상태에서는 Banda의 급여가 7000으로 설정되었다.
롤백과 트랜잭션 대기 - 트랜잭션 대기(Waiting) #4

- 두 번째 세션에서 Greene의 급여를 조회하여 기존 값 9500을 확인한다. 이때, 두 번째 세션은 첫 번째 세션에서 이루어진 Banda의 변경 작업을 직접 확인할 수 없다.
롤백과 트랜잭션 대기 - 트랜잭션 대기(Waiting) #5

첫 번째 세션: Banda의 Salary를 7000으로 업데이트.
두 번째 세션: 첫 번째 세션의 변경 사항이 반영되지 않은 상태로 조회되어 원래 Salary 값(6200)이 표시됨.
💡포인트: Commit되지 않은 변경 사항은 다른 세션에서 볼 수 없음: 트랜잭션이 Commit되어야 다른 세션에서도 변경된 데이터를 조회할 수 있다.
롤백과 트랜잭션 대기 - 트랜잭션 대기(Waiting) #6
💡요약: 아래의 예제는 트랜잭션 대기가 데이터베이스에서 자원의 충돌을 방지하고 일관성을 유지하기 위해 어떻게 동작하는지 보여주고 있다. Commit이 완료되기 전에는 다른 세션이 해당 자원에 접근하지 못하도록 잠금을 걸어 데이터의 무결성을 유지하는 중요한 기능이다.

첫 번째 세션: Banda의 Salary를 7000으로 업데이트했으나 Commit하지 않음.
두 번째 세션: Banda의 Salary를 10000으로 업데이트 시도했지만, 첫 번째 세션의 Commit이 완료될 때까지 대기 상태이기 때문에 아무런 결과가 뜨지 않는다.
롤백과 트랜잭션 대기 - 트랜잭션 대기(Waiting) #7
💡요약: 아래 이미지는 트랜잭션 대기 (Waiting) 상황에서 첫 번째 세션에서 Commit을 실행하면, 두 번째 세션이 대기하고 있던 작업이 즉시 실행되는 과정을 보여주고 있다.

첫 번째 세션에서 Commit 실행
- 첫 번째 세션에서 Banda의 Salary를 7000으로 업데이트한 후 Commit을 실행한다. Commit이 완료되면 해당 트랜잭션의 변경 사항이 데이터베이스에 영구적으로 저장된다.
두 번째 세션의 대기 상태 해제 및 작업 실행
- 첫 번째 세션에서 Commit을 완료하자, 두 번째 세션에서 대기하던 Banda의 Salary를 10000으로 변경하는 작업이 즉시 실행된다. Commit이 이루어져야만 다른 세션이 해당 데이터에 접근하거나 수정할 수 있게 된다.
롤백과 트랜잭션 대기 - 트랜잭션 롤백(Rollback)
💡요약: Rollback은 트랜잭션 도중 문제가 발생했을 때 데이터베이스의 무결성을 유지하고, 원래 상태로 안전하게 복구할 수 있는 기능이다.
Rollback: 트랜잭션을 수행 전 상태로 되돌림.
undo segment: 트랜잭션에서 수행한 작업을 반대로 적용.
락 해제 및 세이브포인트 삭제: 롤백 후 자원 잠금 해제 및 모든 임시 저장 지점 제거.
롤백은 트랜잭션이 수행되기 전 상태로 되돌림
- Rollback을 실행하면 트랜잭션이 시작되기 전의 상태로 돌아간다. 이는 데이터 무결성을 유지하기 위한 중요한 기능이다.
트랜잭션이 롤백되면 더 이상 존재하지 않는 상태가 됨
- 트랜잭션이 롤백된 후에는 해당 트랜잭션의 변경 사항이 사라지며, 데이터베이스는 마치 해당 트랜잭션이 없었던 것처럼 처리된다.
롤백 명령어를 만나면 수행되는 작업
undo segment를 사용하여 해당 작업을 반대로 적용한다. 예를 들어, 삽입된 데이터는 삭제되고, 업데이트된 데이터는 원래 값으로 복구된다.
트랜잭션 중 걸린 락(lock)을 해제한다.
모든 세이브포인트 (Savepoint)를 삭제한다.
트랜잭션을 종료한다.
ROLLBACK;
위 명령어는 트랜잭션을 모두 되돌려서 원래 상태로 복구시키는 명령어이다. 예를 들어, 트랜잭션 도중에 데이터 수정이 발생했으나 오류가 발견되었을 때 ROLLBACK을 통해 변경 사항을 취소할 수 있게 된다.


