Transaction(트랜잭션) 개념과 접근방식
프로그래밍에서 트랜잭션(Transaction) 은 아주 기본적이고 중요한 개념입니다.
이번 포스팅에서는 트랜잭션의 정의와 작동 방식, 트랜잭션을 다루는 주요 접근 방식에 대해 정리를 해보았습니다.
이 개념을 잘 이해하고 있으면,
개발 과정에서의 오류 대응과 안정적인 데이터 처리 로직을 설계하는 데 큰 도움이 됩니다!
특히, 트랜잭션 오류는 실제 개발 환경에서 자주 발생하는 이슈 중 하나이므로, 기본기를 탄탄히 다져두는 것이 중요합니다.
트랜잭션이란?
트랜잭션은 데이터베이스의 상태를 변경시키기 위해 수행하는 하나의 작업 단위입니다.
즉, 하나 이상의 쿼리를 묶어 논리적으로 하나의 작업처럼 처리하는 것을 의미합니다.
🔸 모든 작업이 정상적으로 완료되면 → 데이터베이스에 영구적으로 반영(commit)
🔸 중간에 하나라도 실패하면 → 이전 작업들을 모두 취소하고 원상복구(rollback)
💡 예시
A -> B -> C 를 처리하는 로직이 있을때,
A는 오류 없이 실행을 완료하였고 B를 실행하는 도중에 오류가 발생한다면
A,B 작업 모두가 롤백(roll-back) 처리가 된다.
A부터 C까지 정상적으로 실행을 완료하면
해당 작업에 대해서 커밋(commit) 처리가 된다.
Commit 이란?
하나의 트랜잭션이 성공적으로 끝나서 데이터베이스가 일관성있는 상태에 있음을 의미한다.
Rollback 이란?
트랜잭션의 원자성이 깨질 때,
즉 하나의 트랜잭션 처리가 비정상적으로 종료 되었을 때의 상태를 뜻한다.
Rollback 이 이뤄진다면 트랜잭션을 다시 실행하거나 부분적으로 변경된 결과를 취소할 수 있다.
🔍 이 두 개념은 트랜잭션에서 핵심이므로 반드시 숙지하고 있어야 합니다.
SQLD 시험에서도 자주 등장하는 기본 개념입니다.
트랜잭션의 4대 속성: ACID
트랜잭션은 아래와 같이 ACID 속성을 따라야 합니다.
- 원자성 (Atomicity)
- 트랜잭션내 모든 작업이 성공적으로 수행되거나 아무런 변경도 발생하지 않은 상태여야 한다.
- 일관성 (Consistency)
- 트랜잭션이 실행되기 전과 후에도 데이터베이스의 상태가 일관성이 있어야 한다.
- 격리성 (Isolation)
- 여러 개의 트랜잭션이 동시에 실행될 때 각각의 트랜잭션은 다른 트랜잭션에 영향을 주지 않도록 격리되어야 한다. 하나의 트랜잭션이 완료되기 전까지 다른 트랜잭션은 해당 작업에 대한 변경 사항을 알 수 없어야 한다.
- 지속성 (Durability)
- 트랜잭션을 성공적으로 끝내면 그 결과가 항상 기록되어야 합니다. 중간에 시스템에 문제가 발생하더라도 데이터베이스 로그 등을 사용해서 성공한 트랜잭션 내용을 복구해야 한다.
트랜잭션 접근 방식이란?
트랜잭션 접근 방식은 트랜잭션을 어떻게 다루고 조작하는지를 나타내는 개념이다.
트랜잭션을 다루는 방식은 크게 두 가지로 나뉩니다.
프로그래밍적 트랜잭션(명시적 트랜잭션)과 선언적 트랜잭션이다.
1. 프로그래밍적 트랜잭션 (Programmatic Transaction)
개발자가 명시적으로 트랜잭션을 시작하여,
커밋 또는 롤백하는 코드를 작성하여 트랜잭션을 직접 관리하는 방식입니다.
- 트랜잭션 API 또는 관리 객체를 통해 직접 처리한다.
- 세밀한 제어가 가능하다. (특정 조건에서만 커밋/롤백 등)
- Spring에서는 TransactionTemplate, PlatformTransactionManager 등을 사용한다.
TransactionTemplate template = new TransactionTemplate(transactionManager);
template.execute(status -> {
// 트랜잭션 내에서 실행할 로직
return someResult;
});
🚨 단점: 코드가 장황해지고, 중복되는 트랜잭션 처리 코드가 많아질 수 있다.
2. 선언적 트랜잭션 (Declarative Transaction)
트랜잭션을 선언적으로 정의하고,
프레임워크나 컨테이너가 해당 정의에 따라 트랜잭션을 자동으로 관리하는 방식이다.
- @Transactional 애노테이션을 메서드 또는 클래스에 선언
- 시작/종료를 개발자가 직접 다룰 필요가 없다.
- 코드 가독성이 좋아지며 유지보수에 좋다.
@Transactional
public void updateUserInfo(User user) {
// 자동으로 트랜잭션이 시작되고, 성공 시 커밋됨
}
🚨 단점: 세밀한 조건 제어나 예외 처리에는 제약이 있을 수 있다.
언제 어떤 방식이 적합할까?
특정 로직 조건에 따라 트랜잭션 제어가 필요할 때 | 프로그래밍적 트랜잭션 |
일반적인 서비스 로직에서 단순하게 트랜잭션 적용할 때 | 선언적 트랜잭션 |
각각의 방식은 트랜잭션 관리의 목적과 요구사항에 따라 선택하여 사용하면 된다.
😎
'DB' 카테고리의 다른 글
[ERD] 이클립스 ER Master 사용법 그리고 ERD 추출, JAVA DOC 추출시 인코딩 에러 해결 (1) | 2024.07.11 |
---|---|
[DB/SQL] 뷰(View) 그리고 프로시저(Procedure) 개념 (3) | 2024.02.29 |
[DB] 스프링부트 트랜잭션 @Transactional (2) | 2024.02.21 |
[SQL] MySql에서 함수를 사용하는것과 사용하지 않는것에 대한 속도 차이 (4) | 2024.01.07 |
[DB] DBeaver(디비버)로 Tibero(티베로) 연결하기 (2) | 2023.12.11 |