물리 트랜잭션과 논리 트랜잭션은 데이터베이스 트랜잭션과 애플리케이션 레이어에서의 트랜잭션 동작을 구분하는 개념으로, 특히 스프링에서의 트랜잭션 관리와 관련하여 자주 언급됩니다.
1. 물리 트랜잭션 (Physical Transaction)
정의
• 데이터베이스(DB)와 직접적으로 연결된 트랜잭션입니다.
• DB 레벨에서 커밋(Commit)과 롤백(Rollback)을 관리합니다.
• 하나의 Connection을 사용하여 트랜잭션 경계를 설정합니다.
특징
• 실제로 DB에서 트랜잭션이 시작되고, 상태가 변경되거나 데이터를 조회합니다.
• 트랜잭션이 끝날 때 DB에 커밋되거나 롤백됩니다.
예시
START TRANSACTION;
-- 데이터 수정
UPDATE accounts SET balance = balance - 100 WHERE id = 1;
UPDATE accounts SET balance = balance + 100 WHERE id = 2;
COMMIT;
2. 논리 트랜잭션 (Logical Transaction)
정의
• 애플리케이션 레벨에서의 트랜잭션입니다.
• 스프링 프레임워크에서는 @Transactional을 통해 논리 트랜잭션을 관리합니다.
• 여러 논리 트랜잭션이 하나의 물리 트랜잭션에 매핑될 수 있습니다.
특징
• 애플리케이션 코드에서 트랜잭션 범위를 설정하고 관리합니다.
• 논리 트랜잭션은 물리 트랜잭션에 의존하며, 여러 논리 트랜잭션이 같은 물리 트랜잭션 컨텍스트를 공유할 수 있습니다.
• 트랜잭션 전파(Propagation)에 따라 논리 트랜잭션이 물리 트랜잭션과 독립적으로 실행되거나 하나로 묶일 수 있습니다.
3. 물리 트랜잭션과 논리 트랜잭션의 관계
관계
• 물리 트랜잭션은 DB와 연결되어 있고, 논리 트랜잭션은 애플리케이션 코드 레벨에서 관리됩니다.
• 스프링은 물리 트랜잭션을 기반으로 논리 트랜잭션을 관리합니다.
• @Transactional로 선언된 메서드가 호출될 때 논리 트랜잭션이 생성됩니다.
예시
1. 하나의 물리 트랜잭션, 하나의 논리 트랜잭션
Repository 구현:
OrderRepository
@Repository
public interface OrderRepository extends JpaRepository<Order, Long> {
// JpaRepository를 상속하면 기본적인 CRUD 메서드가 제공됩니다.
}
PaymentRepository
@Repository
public interface PaymentRepository extends JpaRepository<Payment, Long> {
// JpaRepository를 상속하면 기본적인 CRUD 메서드가 제공됩니다.
}
ProcessOrder
@Transactional
public void processOrder() {
orderRepository.save(order);
paymentRepository.save(payment);
}
• 하나의 트랜잭션이 시작되고, orderRepository와 paymentRepository의 작업이 같은 물리 트랜잭션 안에서 수행됩니다.
2. 하나의 물리 트랜잭션, 여러 논리 트랜잭션
OrderService
@Service
public class OrderService {
@Transactional
public void saveOrder(Order order) {
// 주문 저장 관련 비즈니스 로직
System.out.println("주문 저장 로직 실행");
orderRepository.save(order); // 주문 데이터를 데이터베이스에 저장
}
@Autowired
private OrderRepository orderRepository;
}
PaymentService
@Service
public class PaymentService {
@Transactional
public void processPayment(Payment payment) {
// 결제 처리 관련 비즈니스 로직
System.out.println("결제 처리 로직 실행");
paymentRepository.save(payment); // 결제 데이터를 데이터베이스에 저장
}
@Autowired
private PaymentRepository paymentRepository;
}
processOrder 메서드 (Controller 또는 Main Service)
@Transactional
public void processOrder() {
orderService.saveOrder();
paymentService.processPayment();
}
• processOrder 메서드에서 @Transactional을 사용하면 하나의 물리 트랜잭션이 생성됩니다.
• saveOrder와 processPayment는 같은 물리 트랜잭션을 공유하며 논리적으로 구분됩니다.
3. 여러 물리 트랜잭션
• 트랜잭션 전파 속성을 **REQUIRES_NEW**로 설정하면 각 메서드가 독립적인 물리 트랜잭션을 생성합니다.
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void saveOrder() {
// 독립적인 물리 트랜잭션
orderRepository.save(order);
}
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void processPayment() {
// 독립적인 물리 트랜잭션
paymentRepository.save(payment);
}
4. 물리 트랜잭션과 논리 트랜잭션 요약
특징 | 물리 트랜잭션 | 논리 트랜잭션 |
위치 | DB 레벨 | 애플리케이션 레벨 |
관리 주체 | DBMS | 스프링 프레임워크 |
트랜잭션 전파 | 개념 없음 | 전파 속성에 따라 논리 트랜잭션 분리 가능 |
관계 | 하나의 물리 트랜잭션에 여러 논리 트랜잭션 연결 가능 | 물리 트랜잭션 없이 독립적으로 존재할 수 없음 |
+중요한 추가 포인트
• 트랜잭션 전파(Propagation):
논리 트랜잭션에서 중요한 개념으로, 부모-자식 트랜잭션 간의 관계를 제어합니다.
• REQUIRED: 부모 트랜잭션이 있으면 재사용, 없으면 새로 생성.
• REQUIRES_NEW: 항상 새로운 물리 트랜잭션 생성.
• NESTED: 부모 트랜잭션 내에서 자식 논리 트랜잭션 생성.
• 트랜잭션 격리 레벨(Isolation Level):
물리 트랜잭션과 밀접한 관련이 있으며, 트랜잭션 간 데이터 읽기/쓰기 간섭을 제어합니다.
'spring' 카테고리의 다른 글
[Spring] AOP 실제 적용 예시 (1) | 2024.11.29 |
---|---|
[Spring] AOP(Aspect-Oriented Programming) (0) | 2024.11.29 |
[Spring] @Transaction (1) | 2024.11.28 |
[Spring] Spring의 트랜잭션 동기화(Transaction Synchronization) (0) | 2024.11.28 |
[Spring] JdbcTemplate (0) | 2024.11.22 |