트랜잭션(Transaction)은 데이터베이스에서 하나의 논리적 작업 단위를 의미합니다. 여러 SQL 명령을 하나의 단위로 묶어 모두 성공하거나 모두 실패해야만 데이터 정합성을 유지할 수 있습니다.
| 속성 | 설명 |
|---|---|
| Atomicity (원자성) | 모든 작업이 전부 성공하거나 전부 실패해야 함 |
| Consistency (일관성) | 트랜잭션 전후의 데이터가 항상 일관성 유지 |
| Isolation (격리성) | 동시에 실행되는 트랜잭션 간 간섭 방지 |
| Durability (지속성) | 커밋된 트랜잭션은 시스템 오류 발생해도 유지됨 |
| 명령어 | 설명 |
|---|---|
BEGIN | 트랜잭션 시작 |
COMMIT | 성공적으로 종료, 변경사항 반영 |
ROLLBACK | 오류 발생 시 변경사항 취소 |
SAVEPOINT | 중간 저장점 설정 |
RELEASE SAVEPOINT | 저장점 해제 |
BEGIN;
UPDATE accounts SET balance = balance - 10000 WHERE id = 1;
UPDATE accounts SET balance = balance + 10000 WHERE id = 2;
COMMIT;
ROLLBACK으로 두 작업 모두 취소 가능트랜잭션 간 간섭을 얼마나 허용할 것인지 설정하는 기준입니다.
| 수준 | 허용 정도 | 발생할 수 있는 문제 |
|---|---|---|
| READ UNCOMMITTED | 커밋 안 된 데이터 읽음 | Dirty Read |
| READ COMMITTED | 커밋된 데이터만 읽음 | Non-repeatable Read |
| REPEATABLE READ | 읽은 데이터 고정 | Phantom Read |
| SERIALIZABLE | 완벽한 격리, 가장 안전 | 성능 저하 가능 |
Spring에서는 @Transactional 어노테이션으로 트랜잭션을 선언적(명시적 코드 없이)으로 설정할 수 있습니다.
@Transactional
public void transfer(Long fromId, Long toId, int amount) {
accountRepository.withdraw(fromId, amount);
accountRepository.deposit(toId, amount);
}
withdraw()도 자동으로 롤백COMMIT 처리됨@Transactional(rollbackFor = SQLException.class)
public void doSomething() throws SQLException {
// 예외 발생 시 롤백됨
}
@Transactional을 붙이면 테스트 종료 시 자동으로 롤백되어 DB 상태가 유지됨@SpringBootTest
@Transactional
public class UserServiceTest {
// 테스트 DB 변경 후 자동 롤백됨
}
트랜잭션은 단순한 DB 조작이 아닌, 데이터 무결성과 동시성 문제를 방지하기 위한 핵심 개념입니다. 제대로 이해하고 설계에 반영하는 것이 안정적인 서비스 운영의 출발점입니다.