트랜잭션은 데이터베이스에서 하나의 논리적인 작업 단위를 의미한다. 여러 개의 SQL 명령문이 하나의 트랜잭션으로 묶여 원자적으로 수행되며, 트랜잭션이 완전히 실행되거나 아예 실행되지 않아야 한다.
예를 들어 내가 친구에게 5만원을 송금한다고 쳐보자.

먼저 내 계좌에서 5만원이 빠져나갈 것이고 이를 친구의 계좌로 5만원을 송금한다. 이 과정에서 문제가 없을 경우 친구의 계좌에 5만원이 성공적으로 입금된다.
하지만 송금 과정에서 오류가 발생할 경우 내 계좌에서 이미 5만원은 빠져나갔지만 친구의 계좌에는 아무것도 입금되지 않는다. 결국 나의 5만원은 증발해버리는 것이다.
이러한 사태를 방지하기 위해 트랜잭션은 매우 중요하다.
트랜잭션은 ACID라는 트랜잭션이 안전하고 신뢰할 수 있도록 보장하는 4가지 필수 특성을 가진다.

따라서 앞서 말한 상황에서, 트랜잭션은 5만원 송금에 실패할 경우 롤백을 통해 앞서 진행했던 작업인 5만원 출금을 취소하고 내 계좌에 다시 입금한다. 이로써 송금에 실패하더라도 5만원이 증발하지 않고 원래 상태로 복구된다.
이는 트랜잭션의 가장 중요한 특징인 "모든 작업이 하나의 단위로 묶여 전부 성공하든지, 아니면 전부 실패하든지 둘 중 하나만 보장한다"는 원자성을 보장한다.
데이터베이스에서 SQL 문이 실행될 때 자동으로 Commit이 수행되는 기능이다. 기본적으로 Auto Commit이 활성화되어 있으며 SET AUTOCOMMIT = OFF 명령어를 사용하여 해제할 수 있다.
참고로 DDL은 자동 커밋이 되며 Rollback으로 되돌릴 수 없기 때문에, 신중하게 사용해야 한다.
1️⃣ 트랜잭션 시작
BEGIN TRANSACTION; 또는 START TRANSACTION;2️⃣ Commit 실행
COMMIT;3️⃣ Rollback 실행
ROLLBACK;4️⃣ 저장점 설정 및 복구
SAVEPOINT 저장점이름; 및 ROLLBACK TO 저장점이름;여러 트랜잭션이 동시에 수행될 때, 각 트랜잭션 간에 어떤 영향을 주고받을지를 결정하는 설정
한 트랜잭션이 Commit하지 않은 데이터의 변경 사항을 다른 트랜잭션이 조회할 수 있으며, Dirty Read, Non-Repeatable Read, Phantom Read 문제가 발생할 수 있다.
💡 Dirty Read, Non-repeatable Read, Phantom Read란?
Dirty Read
- 한 트랜잭션이 다른 트랜잭션이 변경 중인 데이터를 읽는 경우 발생
- 다른 트랜잭션이 아직 커밋되지 않은 데이터를 읽은 뒤, 해당 데이터가 나중에 롤백될 경우 트랜잭션의 결과가 변경될 수 있음
- 데이터의 일관성을 깨뜨릴 수 있음
Non-repeatable Read
- 같은 트랜잭션 안에서 동일한 쿼리를 실행했을 때, 그 사이에 UPDATE 작업이 수행되어 다른 데이터를 얻는 경우 발생
Phantom Read
- 한 트랜잭션이 동일한 쿼리를 두 번 실행했을 때, 두 번의 쿼리 사이에 다른 트랜잭션이 INSERT, DELETE의 작업을 수행하여 없던 데이터 행이 새로 생기거나 사라지는 경우 발생
- 트랜잭션 내에서 일관성 없는 결과를 가져올 수 있음
Commit된 데이터만 읽을 수 있으며 트랜잭션이 진행 중인 동안 다른 트랜잭션이 변경한 데이터를 볼 수 없다. Non-repeatable Read, Phantom Read 문제가 발생할 수 있다.
하나의 트랜잭션이 시작되면 특정 레코드를 같은 쿼리로 조회할 때 같은 결과를 보장한다. SERIALIZABLE과 다르게 행이 추가되는 것을 막지는 않으며, Phantom Read가 발생할 수 있다.
가장 엄격한 격리 수준으로 특정 트랜잭션이 사용중인 테이블의 모든 행을 다른 트랜잭션이 접근할 수 없도록 잠가 트랜잭션을 순차적으로 실행하는 것과 같은 효과를 보장한다. 가장 높은 데이터 정합성을 가지지만, 성능 저하가 발생할 수 있다. MySQL은 단순한 SELECT 쿼리가 실행되더라도 데이터베이스 잠금이 걸려 다른 트랜잭션에서 데이터에 접근할 수 없다.
다수의 사용자가 동시에 데이터베이스에 접근할 때 발생할 수 있는 문제를 방지하는 기법으로, 대표적인 동시성 제어 기법에는 3가지가 있다.
| 동시성 제어 기법 | 설명 |
|---|---|
| 로킹 기법 | 트랜잭션이 데이터에 잠금(Lock)을 설정하면 다른 트랜잭션은 해당 데이터에 대해 잠금이 해제(UnLock)될 때까지 접근/수정/삭제 불가 |
| 타임 스탬프 기법 | 시스템에서 생성하는 고유 식별자인 타임 스탬프를 트랜잭션에 부여함으로써 트랜잭션 간의 접근 순서를 미리 정함 |
| 적합성 검증(낙관적) | 먼저 트랜잭션을 수행하고 종료할 때 적합성을 검증하여 데이터베이스에 최종 반영 |
두 개 이상의 트랜잭션이 같은 데이터를 동시에 수정할 때 발생하는 문제로 적절한 트랜잭션 격리 수준 설정 또는 Lock 사용하면 된다.
트랜잭션이 데이터베이스의 특정 부분을 보호하는 메커니즘으로 두 가지가 있다.
1️⃣ 공유 락(Shared Lock, S-lock) : 읽기 작업 허용, 다른 트랜잭션의 쓰기 작업 제한
2️⃣ 베타 락(Exclusive Lock, X-lock) : 읽기와 쓰기 모두 제한
두 개 이상의 트랜잭션이 서로의 자원을 점유하면서 무한 대기 상태에 빠지는 현상이다. 다음과 같은 방안으로 해결할 수 있다.
1️⃣ 트랜잭션 타임아웃 설정
2️⃣ 락 순서 준수
3️⃣ 교착 상태 회피 기법 적용