7주차 Unit 6.1 — PlatformTransactionManager 인터페이스 추상화

Psj·2026년 6월 5일

F-lab

목록 보기
231/240

Unit 6.1 — PlatformTransactionManager 인터페이스 추상화

F-LAB JAVA · 7주차 · Phase 6 · PlatformTransactionManager
🎯 Phase 6 시작 — Spring 의 트랜잭션 추상화


📌 학습 목표

이 Unit을 끝내면 다음을 답할 수 있어야 한다.

  • PlatformTransactionManager 의 정의는?
  • 인터페이스 추상화 의 의미는?
  • 3가지 핵심 메서드 는?
  • 5주차 DIP 정신 의 재현은?
  • 6주차 DataSource 와 같은 사상 은?
  • 인터페이스 의존 (OCP) 의 가치는?
  • TransactionStatus / TransactionDefinition 은?
  • TransactionTemplate 의 활용은?
  • Phase 6.2 (3가지 구현체) 예고는?

🎯 핵심 한 문장

PlatformTransactionManager 는 Spring 의 트랜잭션 추상화 인터페이스로 getTransaction · commit · rollback 3 메서드만 정의해 5주차 DIP (의존성 역전) + 6주차 DataSource 와 동일한 구조를 트랜잭션에 적용 — 애플리케이션은 인터페이스에만 의존하고 실제 구현체 (DataSourceTransactionManager / HibernateTransactionManager / JpaTransactionManager) 는 상황에 맞게 선택해 교체할 수 있으며 이것이 @Transactional 자동화의 직접적 기반이다.
PlatformTransactionManager 는 Spring 의 트랜잭션 추상화 핵심 인터페이스 다 (org.springframework.transaction).
3 메서드 만 정의 — getTransaction(definition) (트랜잭션 시작, TransactionStatus 반환), commit(status) (커밋), rollback(status) (롤백) — 이 인터페이스 자체는 동작 X, 구현체 (DataSourceTransactionManager 등) 가 실제 동작.
5주차 DIP / 6주차 DataSource 와 정확히 같은 구조 — 애플리케이션은 인터페이스 (PlatformTransactionManager) 에만 의존 하고 실제 구현체 (DB / ORM 따라) 는 빈으로 주입받아 사용한다 — OCP (Open-Closed Principle) 적용.
구현체 3가지 (Phase 6.2 상세) — (1) DataSourceTransactionManager (JDBC / JdbcTemplate), (2) HibernateTransactionManager (Hibernate 직접), (3) JpaTransactionManager (JPA / Spring Data JPA) — 사용 시 코드 변경 X, 빈 교체만으로 가능.
TransactionTemplate 은 PlatformTransactionManager 를 한 단계 더 추상화 — 람다 (Callback) 로 비즈니스 로직 전달하면 트랜잭션 관리 자동 (수동의 try/catch/finally 대체).
이 추상화 위에 @Transactional 어노테이션 + AOP/프록시 가 얹혀 자동화의 정점이 된다 (Phase 7 ★★★).

비유 — 표준 콘센트와 가전제품

PlatformTransactionManager = 표준 콘센트:

상황:
  - 가전 (애플리케이션 코드)
  - 콘센트 (PlatformTransactionManager 인터페이스)
  - 발전소 (실제 구현체: DataSource/Hibernate/JPA TM)

표준 콘센트:
  - 모든 가전이 같은 콘센트 (220V)
  - 발전소가 어디든 (수력/원자력/태양광) X 상관
  - 콘센트만 알면 됨

PlatformTransactionManager 정신:
  - 애플리케이션 = 인터페이스만 의존
  - 어떤 DB / ORM 이든 같은 방식
  - 5주차 DIP, 6주차 DataSource 와 같음

3 메서드 = 콘센트의 3 단자:
  - getTransaction = 전기 시작
  - commit = 전기 사용 후 정리
  - rollback = 사고 시 차단

5주차 + 6주차 + 7주차 응축:
  - 5주차: 인터페이스 의존 (DIP)
  - 6주차: DataSource 추상화
  - 7주차 Part B: TM 추상화 (같은 정신)

3 구현체 = 3 발전소 (Phase 6.2):
  - JDBC TM (수력)
  - Hibernate TM (원자력)
  - JPA TM (태양광)

TransactionTemplate:
  - 콘센트 + 멀티탭
  - 람다로 비즈니스 전달
  - 트랜잭션 자동

@Transactional (Phase 7):
  - "스마트 가전"
  - 어노테이션만으로
  - 자동

→ PlatformTransactionManager = 표준 콘센트, 인터페이스만 의존, 구현체 교체 가능.


🧭 9개 섹션 로드맵

1. PlatformTransactionManager 정의
2. 인터페이스 추상화의 의미
3. 3가지 핵심 메서드
4. 5주차 DIP 정신 재현
5. 6주차 DataSource 와 같은 사상
6. 인터페이스 의존 (OCP)
7. TransactionStatus / TransactionDefinition
8. TransactionTemplate 활용
9. Phase 6.2 예고 (3가지 구현체)

1️⃣ PlatformTransactionManager 정의

1.1 정의

PlatformTransactionManager:

  Spring 의 트랜잭션 추상화 인터페이스:
    - 패키지: org.springframework.transaction
    - 3 메서드만 정의
    - 구현체가 실제 동작

→ 모든 Spring 트랜잭션의 기반

1.2 인터페이스 선언

package org.springframework.transaction;

public interface PlatformTransactionManager extends TransactionManager {
    
    // 트랜잭션 시작
    TransactionStatus getTransaction(TransactionDefinition definition)
        throws TransactionException;
    
    // 커밋
    void commit(TransactionStatus status) throws TransactionException;
    
    // 롤백
    void rollback(TransactionStatus status) throws TransactionException;
}

1.3 인터페이스 = 약속

인터페이스 = 약속:

  PlatformTransactionManager:
    - "이런 메서드 있다는 약속"
    - 동작 X (자체로는)

  구현체:
    - "약속 지킴"
    - 실제 동작

→ 인터페이스 + 구현체

1.4 추상화의 위치

추상화의 위치:

┌─────────────────────────────────────┐
│   Application Code                   │
└────────────┬────────────────────────┘
             │ PlatformTransactionManager 만 의존
             ↓
┌─────────────────────────────────────┐
│  PlatformTransactionManager (인터페이스) │
└────────────┬────────────────────────┘
             │ 빈으로 주입 (Spring DI)
             ↓
┌──────────────┬──────────────┬──────────────┐
│ DataSource TM │ Hibernate TM │   JPA TM      │
│  (JDBC)       │  (Hibernate) │  (JPA)        │
└──────────────┴──────────────┴──────────────┘

1.5 ILIC 의 맥락

// ILIC 의 트랜잭션 추상화 활용

// 1. 의존성: 인터페이스만
@Service
public class ShipmentService {
    @Autowired
    private PlatformTransactionManager transactionManager;  // 인터페이스
    
    // 실제로는 JpaTransactionManager 가 주입 (Spring Boot 자동)
    // 코드는 모름 (그게 정신)
    
    public void process() {
        TransactionStatus status = transactionManager.getTransaction(
            new DefaultTransactionDefinition()
        );
        try {
            // 비즈니스
            transactionManager.commit(status);
        } catch (Exception e) {
            transactionManager.rollback(status);
            throw e;
        }
    }
}
class PlatformTransactionManager {
    TransactionStatus getTransaction(TransactionDefinition d) { return null; }
    void commit(TransactionStatus s) {}
    void rollback(TransactionStatus s) {}
}
class TransactionStatus {}
class TransactionDefinition {}
class DefaultTransactionDefinition {}
PlatformTransactionManager transactionManager;
@interface Autowired {}
@interface Service {}

1.6 자기 점검 답변

PlatformTransactionManager 의 정의는?

:
1. 인터페이스:

  • Spring 트랜잭션 추상화
  1. 3 메서드:

    • getTransaction / commit / rollback
  2. 패키지:

    • org.springframework.transaction
  3. 약속:

    • 동작 X, 구현체가

2️⃣ 인터페이스 추상화의 의미

2.1 추상화

추상화:

  공통점 추출:
    - JDBC, Hibernate, JPA 의 트랜잭션
    - 공통 동작 (begin/commit/rollback)
    - 인터페이스로 표현

  세부는 숨김:
    - JDBC 의 setAutoCommit
    - Hibernate 의 EntityTransaction
    - JPA 의 EntityTransaction
    - 모두 다른 방식
    
  → 인터페이스 위로는 같음

2.2 추상화의 효과

효과:

  1. 코드 단순:
     - 인터페이스만
     - 세부 모름

  2. 교체 가능:
     - JDBC → JPA 변경 시
     - 구현체만 교체
     - 코드 그대로

  3. 테스트 쉬움:
     - Mock 구현체
     - 단위 테스트

  4. 학습 ↓:
     - 1 인터페이스
     - vs 3 구현체 모두

2.3 6주차 DataSource 회상

6주차 DataSource:

  DataSource (인터페이스):
    - getConnection()

  구현체:
    - HikariDataSource
    - DriverManagerDataSource
    - ...

  애플리케이션:
    - DataSource 의존
    - 구현체 모름

→ 같은 패턴!

2.4 같은 사상

같은 사상:

  6주차 DataSource:
    - Connection 추상화
    - 어떤 풀이든 같은 방식

  7주차 PlatformTransactionManager:
    - 트랜잭션 추상화
    - 어떤 TM 이든 같은 방식

→ 정확히 같음
→ 5주차 디자인 패턴의 적용

2.5 추상화의 비용

추상화의 비용:

  장점:
    - 위 4가지

  비용:
    - 한 단계 더 (호출 깊이)
    - 디버깅 시 추가 단계
    - 학습 곡선

  보통:
    - 비용 < 장점
    - 추상화 활용

2.6 ILIC 의 맥락

ILIC 의 추상화 활용

ILIC = Spring Boot:
  - PlatformTransactionManager 자동 (Spring 이 빈 등록)
  - 구현체: JpaTransactionManager
  - 코드는 인터페이스만

  미래 변경 시 (DB 변경):
    - MySQL → PostgreSQL: 구현체 그대로
    - JPA → JdbcTemplate: 구현체 다를 수
    - 하지만 코드 그대로

  추상화의 가치:
    - 변경 안전
    - 일관 코드

2.7 자기 점검 답변

인터페이스 추상화의 의미는?

:
1. 추상화:

  • 공통점 추출
  1. 효과:

    • 단순 / 교체 / 테스트
  2. 6주차 DataSource:

    • 같은 패턴
  3. 사상:

    • 5주차 디자인 패턴

3️⃣ 3가지 핵심 메서드

3.1 메서드 1 — getTransaction

TransactionStatus getTransaction(TransactionDefinition definition)
    throws TransactionException;
getTransaction:

  의미:
    - 트랜잭션 시작 또는 기존 참여

  파라미터:
    - TransactionDefinition: 트랜잭션 정의
      - 전파 (propagation)
      - 격리 (isolation)
      - timeout
      - readOnly

  반환:
    - TransactionStatus: 트랜잭션 상태
      - 신규 / 기존
      - rollback 표시 가능

3.2 메서드 2 — commit

void commit(TransactionStatus status) throws TransactionException;
commit:

  의미:
    - 트랜잭션 커밋
    - DB 에 영구 반영

  파라미터:
    - TransactionStatus: getTransaction 의 반환

  내부 동작:
    - 변경 사항 DB 반영
    - 락 해제
    - 자원 정리

3.3 메서드 3 — rollback

void rollback(TransactionStatus status) throws TransactionException;
rollback:

  의미:
    - 트랜잭션 롤백
    - 변경 사항 취소

  파라미터:
    - TransactionStatus

  내부 동작:
    - 변경 사항 취소
    - 메모리 정리
    - 자원 정리

3.4 사용 패턴

// 사용 패턴 (수동, 하지만 추상화)
@Service
public class ShipmentService {
    @Autowired PlatformTransactionManager tm;
    
    public void process() {
        // 1. 트랜잭션 시작
        TransactionDefinition def = new DefaultTransactionDefinition();
        TransactionStatus status = tm.getTransaction(def);
        
        try {
            // 2. 비즈니스 로직
            // ...
            
            // 3. 커밋
            tm.commit(status);
        } catch (Exception e) {
            // 4. 롤백
            tm.rollback(status);
            throw e;
        }
    }
}
class PlatformTransactionManager {
    TransactionStatus getTransaction(TransactionDefinition d) { return null; }
    void commit(TransactionStatus s) {}
    void rollback(TransactionStatus s) {}
}
class TransactionStatus {}
class TransactionDefinition {}
class DefaultTransactionDefinition extends TransactionDefinition {}
PlatformTransactionManager tm;

3.5 수동 직접 vs PlatformTM

수동 직접 vs PlatformTM:

  수동 직접 (Phase 5):
    - JDBC: conn.setAutoCommit(false), commit, rollback
    - JPA: em.getTransaction().begin/commit/rollback
    - DB / ORM 별 다름

  PlatformTM:
    - 항상 같음: getTransaction / commit / rollback
    - 구현체가 차이 처리
    - 일관 인터페이스

→ 추상화의 효과

3.6 ILIC 의 맥락

// ILIC 의 PlatformTM 사용 (수동 활용, 자동화 전)

@Service
public class ShipmentService {
    @Autowired 
    private PlatformTransactionManager tm;
    
    @Autowired 
    private ShipmentRepository repo;
    
    public void processShipment(Long id) {
        // 1. 정의
        DefaultTransactionDefinition def = new DefaultTransactionDefinition();
        def.setName("processShipment");
        def.setIsolationLevel(TransactionDefinition.ISOLATION_READ_COMMITTED);
        def.setTimeout(30);
        
        // 2. 시작
        TransactionStatus status = tm.getTransaction(def);
        
        try {
            // 3. 비즈니스 (어떤 ORM 이든)
            Shipment s = repo.findById(id).orElseThrow();
            s.markAsShipped();
            
            // 4. 커밋
            tm.commit(status);
        } catch (Exception e) {
            // 5. 롤백
            tm.rollback(status);
            throw new RuntimeException(e);
        }
    }
}

// → 인터페이스 사용
// → 어떤 TM 이든 같은 코드
// → 수동이지만 추상화
class Shipment { void markAsShipped() {} }
ShipmentRepository repo;
interface ShipmentRepository { java.util.Optional<Shipment> findById(Long id); }
class PlatformTransactionManager {
    TransactionStatus getTransaction(TransactionDefinition d) { return null; }
    void commit(TransactionStatus s) {}
    void rollback(TransactionStatus s) {}
}
class TransactionStatus {}
class TransactionDefinition {
    static int ISOLATION_READ_COMMITTED = 0;
}
class DefaultTransactionDefinition extends TransactionDefinition {
    void setName(String s) {}
    void setIsolationLevel(int i) {}
    void setTimeout(int t) {}
}
PlatformTransactionManager tm;

3.7 자기 점검 답변

3가지 핵심 메서드는?

:
1. getTransaction:

  • 시작 (TransactionStatus)
  1. commit:

    • 커밋
  2. rollback:

    • 롤백
  3. 수동 직접 vs:

    • 일관 인터페이스

4️⃣ 5주차 DIP 정신 재현

4.1 DIP (의존성 역전)

DIP (Dependency Inversion Principle):

  "고수준 모듈은 저수준 모듈에 의존 X.
   둘 다 추상화 (인터페이스) 에 의존."

  애플리케이션 (고수준) →
    PlatformTransactionManager (추상) ←
      DataSourceTransactionManager (저수준)

4.2 추상화 의존

추상화 의존:

  애플리케이션:
    @Autowired PlatformTransactionManager tm;
    // ↑ 인터페이스만 의존

  실제 동작:
    - JpaTransactionManager (실제 구현)
    - 또는 DataSourceTransactionManager
    - 코드는 모름

→ DIP 충족

4.3 OCP (개방-폐쇄)

OCP (Open-Closed Principle):

  "확장에 열려 있고 변경에 닫혀 있어야"

  새 TM 추가 시:
    - 구현체 추가 (확장 OK)
    - 기존 코드 변경 X
    - 빈 등록만

→ OCP 충족

4.4 5주차 패턴 매핑

5주차 패턴 매핑:

  - DI: TM 빈 주입
  - DIP: 인터페이스 의존
  - OCP: 구현체 교체 가능
  - 전략 패턴: TM 이 전략
  - 템플릿 패턴: TransactionTemplate

→ 5주차 디자인 패턴 응축

4.5 같은 정신

같은 정신:

  6주차 DataSource:
    - DataSource (인터페이스)
    - HikariDataSource (구현체)
    - 5주차 DIP 적용

  7주차 PlatformTM:
    - PlatformTransactionManager (인터페이스)
    - DataSourceTM / HibernateTM / JpaTM (구현체)
    - 5주차 DIP 적용

→ 똑같은 패턴
→ "익숙해진 패턴 그대로"

4.6 ILIC 의 맥락

// ILIC 의 5주차 정신 적용

// 5주차 디자인 패턴 적용 결과:

// 1. DI (Spring Boot 가 자동)
@Service
public class ShipmentService {
    @Autowired 
    private PlatformTransactionManager tm;   // DI
}

// 2. DIP
// - 애플리케이션 = 인터페이스 의존
// - 구현체 모름

// 3. OCP
// - 새 TM 추가? 구현체만
// - 기존 코드 X 변경

// 4. 전략 패턴
// - TM = 전략
// - 다른 TM 으로 교체 가능

// 5. 빈 교체 (구현체 변경)
@Bean
public PlatformTransactionManager transactionManager() {
    return new JpaTransactionManager(emf);   // 1. JPA 사용
    // 또는:
    // return new DataSourceTransactionManager(dataSource);   // 2. JDBC
}

// → 5주차 패턴의 완벽 응축
class JpaTransactionManager {
    JpaTransactionManager(EntityManagerFactory emf) {}
}
class DataSourceTransactionManager {
    DataSourceTransactionManager(DataSource ds) {}
}
class PlatformTransactionManager {}
EntityManagerFactory emf;
DataSource dataSource;
class EntityManagerFactory {}
interface DataSource {}
@interface Service {}
@interface Autowired {}
@interface Bean {}

4.7 자기 점검 답변

5주차 DIP 정신의 재현은?

:
1. DIP:

  • 인터페이스 의존
  1. OCP:

    • 확장 가능
  2. 5주차 패턴:

    • DI / 전략 / 템플릿
  3. 같은 정신:

    • 6주차 그대로

5️⃣ 6주차 DataSource 와 같은 사상

5.1 6주차 DataSource 복습

6주차 DataSource:

  javax.sql.DataSource (인터페이스):
    public interface DataSource {
        Connection getConnection() throws SQLException;
        // ...
    }

  구현체:
    - HikariDataSource (가장 빠른 풀)
    - DriverManagerDataSource (단순)
    - C3P0, DBCP, ...

5.2 PlatformTM 과 비교

항목DataSource (6주차)PlatformTransactionManager (7주차)
인터페이스javax.sql.DataSourceorg.springframework.transaction.PlatformTransactionManager
메서드 수여러3 (getTransaction/commit/rollback)
추상화 대상Connection 제공트랜잭션 관리
구현체HikariDataSource 등DataSourceTM, HibernateTM, JpaTM
애플리케이션 의존DataSource 만PlatformTM 만
사상DIP / OCPDIP / OCP (동일)

5.3 같은 구조

같은 구조:

  6주차:
    Application
        ↓ DataSource (인터페이스)
    HikariDataSource (구현체)

  7주차:
    Application
        ↓ PlatformTransactionManager (인터페이스)
    JpaTransactionManager (구현체)

→ 정확히 같음

5.4 학습의 누적

학습의 누적:

  6주차에서 DataSource 학습 →
  7주차에서 PlatformTM 도 같은 패턴 →
  "익숙한 패턴 재인식" →
  깊은 이해

  3-5-6-7주차의 응축:
    - 3주차 (함수형): 람다 (TransactionTemplate)
    - 5주차 (디자인 패턴): DI / DIP / OCP / 템플릿+전략
    - 6주차 (DB 접근): DataSource 추상화
    - 7주차 Part B: 같은 사상으로 TM 추상화

→ 자바 진영 추상화의 일관 사상

5.5 추상화의 깊이

추상화의 깊이:

  Application
    ↓
  PlatformTransactionManager (인터페이스)
    ↓
  JpaTransactionManager (구현체)
    ↓
  EntityManagerFactory (JPA)
    ↓
  DataSource (인터페이스, 6주차)
    ↓
  HikariDataSource (구현체, 6주차)
    ↓
  JDBC Driver
    ↓
  DB

  → 6 단계 추상화!
  → 각 단계 5주차 DIP 적용

5.6 ILIC 의 맥락

ILIC 의 6주차 + 7주차 통합

ILIC 의 빈 구조 (Spring Boot 자동):
  1. HikariDataSource (6주차)
  2. EntityManagerFactory (JPA + Hibernate, 7주차)
  3. JpaTransactionManager (7주차)

  application.yml 설정:
    spring:
      datasource: { url, username, password, hikari }
      jpa: { hibernate, properties }

  Spring Boot:
    - 위 3 빈 모두 자동 생성
    - 자동 연결
    - 코드 X

  애플리케이션:
    @Autowired DataSource dataSource;          // 인터페이스
    @PersistenceContext EntityManager em;       // 인터페이스
    @Autowired PlatformTransactionManager tm;   // 인터페이스
    
    // 모두 인터페이스 의존
    // 5주차 + 6주차 + 7주차 정신

→ ILIC = 추상화의 결정체

5.7 자기 점검 답변

6주차 DataSource 와 같은 사상은?

:
1. 6주차 DataSource:

  • 인터페이스 + 구현체
  1. 7주차 PlatformTM:

    • 같은 패턴
  2. 사상:

    • DIP / OCP
  3. 누적:

    • 학습의 응축

6️⃣ 인터페이스 의존 (OCP)

6.1 OCP 의 적용

OCP 적용:

  애플리케이션:
    - PlatformTransactionManager 만 의존
    - 구현체 모름

  새 TM 추가 시:
    - 구현체 추가 (확장)
    - 기존 코드 변경 X
    - 빈 등록만

→ "확장에 열려, 변경에 닫혀"

6.2 구현체 교체

// 1. JPA 사용 (현재)
@Bean
public PlatformTransactionManager transactionManager(
        EntityManagerFactory emf) {
    return new JpaTransactionManager(emf);
}

// 2. JDBC 로 변경 (가정)
@Bean
public PlatformTransactionManager transactionManager(
        DataSource dataSource) {
    return new DataSourceTransactionManager(dataSource);
}

// 3. Hibernate 직접 (가정)
@Bean
public PlatformTransactionManager transactionManager(
        SessionFactory sessionFactory) {
    return new HibernateTransactionManager(sessionFactory);
}

// 애플리케이션 코드는?
@Autowired PlatformTransactionManager tm;
// → 그대로! 변경 X
class PlatformTransactionManager {}
class JpaTransactionManager extends PlatformTransactionManager {
    JpaTransactionManager(EntityManagerFactory emf) {}
}
class DataSourceTransactionManager extends PlatformTransactionManager {
    DataSourceTransactionManager(DataSource ds) {}
}
class HibernateTransactionManager extends PlatformTransactionManager {
    HibernateTransactionManager(SessionFactory sf) {}
}
EntityManagerFactory emf;
DataSource dataSource;
SessionFactory sessionFactory;
class EntityManagerFactory {}
interface DataSource {}
class SessionFactory {}
PlatformTransactionManager tm;
@interface Bean {}
@interface Autowired {}

6.3 OCP 의 가치

OCP 의 가치:

  1. 변경 안전:
     - 기존 코드 변경 X
     - 새 구현 추가만

  2. 테스트:
     - Mock TM 으로 테스트
     - 단위 테스트

  3. 마이그레이션:
     - JDBC → JPA 등
     - 구현체만 교체

  4. 다중 환경:
     - 개발 / 테스트 / 운영
     - 각자 다른 TM 가능

6.4 다중 TM (실무)

// 다중 TM (멀티 DataSource 등)
@Configuration
public class DataSourceConfig {
    
    @Primary
    @Bean(name = "mainTransactionManager")
    public PlatformTransactionManager mainTM(
            @Qualifier("mainEmf") EntityManagerFactory emf) {
        return new JpaTransactionManager(emf);
    }
    
    @Bean(name = "logTransactionManager")
    public PlatformTransactionManager logTM(
            @Qualifier("logDataSource") DataSource dataSource) {
        return new DataSourceTransactionManager(dataSource);
    }
}

// 사용 시 어떤 TM 인지 명시
@Transactional("mainTransactionManager")
public void mainBusiness() { ... }

@Transactional("logTransactionManager")
public void logging() { ... }
class JpaTransactionManager extends PlatformTransactionManager {
    JpaTransactionManager(EntityManagerFactory emf) {}
}
class DataSourceTransactionManager extends PlatformTransactionManager {
    DataSourceTransactionManager(DataSource ds) {}
}
class PlatformTransactionManager {}
class EntityManagerFactory {}
interface DataSource {}
@interface Configuration {}
@interface Primary {}
@interface Bean { String name(); }
@interface Qualifier { String value(); }
@interface Transactional { String value(); }

6.5 ILIC 의 맥락

// ILIC 의 OCP 적용

// 현재: JPA 사용
// → Spring Boot 가 JpaTransactionManager 자동 등록

// 미래 가능성:
// 1. 멀티 DB (메인 + 로그 분리)
//    → 2개 TM
// 2. JDBC + JPA 혼합
//    → 두 TM
// 3. 분산 트랜잭션 (XA)
//    → JtaTransactionManager

// 어떤 변경이든 애플리케이션 코드:
@Service
public class ShipmentService {
    @Autowired PlatformTransactionManager tm;   // 그대로
    
    @Transactional   // 또는 어노테이션 (Phase 7)
    public void process() { ... }
}

// → 인터페이스 의존 = 변경 안전
class PlatformTransactionManager {}
PlatformTransactionManager tm;
@interface Service {}
@interface Autowired {}
@interface Transactional {}

6.6 자기 점검 답변

인터페이스 의존 (OCP) 의 가치는?

:
1. OCP:

  • 확장 / 변경 X
  1. 구현체 교체:

    • 빈 변경만
  2. 다중 TM:

    • 가능
  3. 가치:

    • 안전 / 테스트 / 마이그레이션

7️⃣ TransactionStatus / TransactionDefinition

7.1 TransactionDefinition

TransactionDefinition:

  트랜잭션의 "설정 / 정의":
    - propagation (전파)
    - isolation (격리)
    - timeout
    - readOnly
    - name (이름, 디버깅용)

  getTransaction 의 입력

7.2 인터페이스

package org.springframework.transaction;

public interface TransactionDefinition {
    
    // 전파 (propagation)
    int PROPAGATION_REQUIRED = 0;       // 기본
    int PROPAGATION_SUPPORTS = 1;
    int PROPAGATION_MANDATORY = 2;
    int PROPAGATION_REQUIRES_NEW = 3;
    int PROPAGATION_NOT_SUPPORTED = 4;
    int PROPAGATION_NEVER = 5;
    int PROPAGATION_NESTED = 6;
    
    // 격리 (isolation)
    int ISOLATION_DEFAULT = -1;
    int ISOLATION_READ_UNCOMMITTED = 1;
    int ISOLATION_READ_COMMITTED = 2;
    int ISOLATION_REPEATABLE_READ = 4;
    int ISOLATION_SERIALIZABLE = 8;
    
    // 메서드들
    int getPropagationBehavior();
    int getIsolationLevel();
    int getTimeout();
    boolean isReadOnly();
    String getName();
}

7.3 DefaultTransactionDefinition

// 기본 구현체
DefaultTransactionDefinition def = new DefaultTransactionDefinition();

// 옵션 설정
def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
def.setIsolationLevel(TransactionDefinition.ISOLATION_READ_COMMITTED);
def.setTimeout(30);   // 초
def.setReadOnly(true);
def.setName("processShipment");
class TransactionDefinition {
    static int PROPAGATION_REQUIRED = 0;
    static int ISOLATION_READ_COMMITTED = 2;
}
class DefaultTransactionDefinition extends TransactionDefinition {
    void setPropagationBehavior(int i) {}
    void setIsolationLevel(int i) {}
    void setTimeout(int t) {}
    void setReadOnly(boolean b) {}
    void setName(String s) {}
}

7.4 TransactionStatus

TransactionStatus:

  트랜잭션의 "현재 상태":
    - 신규 / 기존
    - rollback 표시 가능
    - 메타 정보

  getTransaction 의 반환
  commit / rollback 의 입력

7.5 TransactionStatus 메서드

package org.springframework.transaction;

public interface TransactionStatus extends TransactionExecution, SavepointManager, Flushable {
    
    // 신규 트랜잭션 여부
    boolean isNewTransaction();
    
    // rollback only 표시 (commit 시도 시 rollback)
    void setRollbackOnly();
    boolean isRollbackOnly();
    
    // 완료 여부
    boolean isCompleted();
    
    // SavePoint 생성 (NESTED)
    Object createSavepoint();
    void rollbackToSavepoint(Object savepoint);
    void releaseSavepoint(Object savepoint);
}

7.6 사용 예시

// 전체 사용 예시
@Service
public class ShipmentService {
    @Autowired PlatformTransactionManager tm;
    
    public void process(Long id) {
        // 1. Definition
        DefaultTransactionDefinition def = new DefaultTransactionDefinition();
        def.setIsolationLevel(TransactionDefinition.ISOLATION_READ_COMMITTED);
        def.setTimeout(30);
        def.setReadOnly(false);
        
        // 2. 시작
        TransactionStatus status = tm.getTransaction(def);
        
        try {
            // 3. 비즈니스
            Shipment s = repo.findById(id).orElseThrow();
            
            if (!s.canProcess()) {
                status.setRollbackOnly();   // ← rollback 예약
                // 또는 throw
            } else {
                s.process();
            }
            
            // 4. 커밋 (rollback only 면 commit 시도해도 rollback)
            tm.commit(status);
        } catch (Exception e) {
            tm.rollback(status);
            throw e;
        }
    }
}
class Shipment {
    boolean canProcess() { return false; }
    void process() {}
}
ShipmentRepository repo;
interface ShipmentRepository { java.util.Optional<Shipment> findById(Long id); }
class PlatformTransactionManager {
    TransactionStatus getTransaction(TransactionDefinition d) { return null; }
    void commit(TransactionStatus s) {}
    void rollback(TransactionStatus s) {}
}
PlatformTransactionManager tm;
class TransactionStatus { void setRollbackOnly() {} }
class TransactionDefinition { static int ISOLATION_READ_COMMITTED = 2; }
class DefaultTransactionDefinition extends TransactionDefinition {
    void setIsolationLevel(int i) {}
    void setTimeout(int t) {}
    void setReadOnly(boolean b) {}
}
@interface Service {}
@interface Autowired {}

7.7 ILIC 의 맥락

// ILIC 의 활용 (수동, 자동화 전)

@Service
public class ShipmentService {
    @Autowired PlatformTransactionManager tm;
    
    public List<Shipment> findAll() {
        // 읽기 전용 트랜잭션
        DefaultTransactionDefinition def = new DefaultTransactionDefinition();
        def.setReadOnly(true);
        def.setIsolationLevel(TransactionDefinition.ISOLATION_READ_COMMITTED);
        def.setName("findAll");
        
        TransactionStatus status = tm.getTransaction(def);
        try {
            List<Shipment> result = repo.findAll();
            tm.commit(status);
            return result;
        } catch (Exception e) {
            tm.rollback(status);
            throw e;
        }
    }
}

// → 명시적 트랜잭션 설정
// → @Transactional (Phase 7) 로 더 간단
class Shipment {}
ShipmentRepository repo;
interface ShipmentRepository { java.util.List<Shipment> findAll(); }
class PlatformTransactionManager {
    TransactionStatus getTransaction(TransactionDefinition d) { return null; }
    void commit(TransactionStatus s) {}
    void rollback(TransactionStatus s) {}
}
PlatformTransactionManager tm;
class TransactionStatus {}
class TransactionDefinition { static int ISOLATION_READ_COMMITTED = 2; }
class DefaultTransactionDefinition extends TransactionDefinition {
    void setReadOnly(boolean b) {}
    void setIsolationLevel(int i) {}
    void setName(String s) {}
}

7.8 자기 점검 답변

TransactionStatus / TransactionDefinition 은?

:
1. TransactionDefinition:

  • 설정 (propagation / isolation / timeout / readOnly)
  1. TransactionStatus:

    • 현재 상태 / rollback only
  2. DefaultTransactionDefinition:

    • 기본 구현
  3. 사용:

    • 명시적 설정

8️⃣ TransactionTemplate 활용

8.1 TransactionTemplate

TransactionTemplate:

  PlatformTransactionManager 위의 추상화:
    - 람다 (Callback) 로 비즈니스 전달
    - try/catch/finally 자동
    - 6주차 JdbcTemplate 와 같은 정신

→ 수동 vs 어노테이션 중간

8.2 사용

// TransactionTemplate 사용
@Service
public class ShipmentService {
    @Autowired TransactionTemplate transactionTemplate;
    @Autowired ShipmentRepository repo;
    
    public Shipment process(Long id) {
        return transactionTemplate.execute(status -> {
            // 비즈니스만!
            Shipment s = repo.findById(id).orElseThrow();
            s.markAsShipped();
            return s;
        });
        // 자동:
        // - 트랜잭션 시작
        // - 메서드 실행
        // - 정상 → commit
        // - 예외 → rollback
    }
    
    // void 일 경우
    public void update(Long id) {
        transactionTemplate.executeWithoutResult(status -> {
            // 비즈니스
        });
    }
}
class Shipment { void markAsShipped() {} }
ShipmentRepository repo;
interface ShipmentRepository { java.util.Optional<Shipment> findById(Long id); }
class TransactionTemplate {
    <T> T execute(java.util.function.Function<TransactionStatus, T> f) { return null; }
    void executeWithoutResult(java.util.function.Consumer<TransactionStatus> c) {}
}
TransactionTemplate transactionTemplate;
class TransactionStatus {}

8.3 TransactionTemplate 의 내부

// TransactionTemplate 의 동작 (개념)
public <T> T execute(TransactionCallback<T> action) {
    TransactionStatus status = transactionManager.getTransaction(this);
    
    T result;
    try {
        result = action.doInTransaction(status);
    } catch (Exception e) {
        // 롤백
        transactionManager.rollback(status);
        throw e;
    }
    
    transactionManager.commit(status);
    return result;
}
// → 5주차 템플릿+전략 패턴
// → 변하지 않는 부분 (트랜잭션 관리)
// → 변하는 부분 (Callback)
class TransactionCallback<T> { T doInTransaction(TransactionStatus s) { return null; } }
class PlatformTransactionManager {
    TransactionStatus getTransaction(Object def) { return null; }
    void commit(TransactionStatus s) {}
    void rollback(TransactionStatus s) {}
}
class TransactionStatus {}
PlatformTransactionManager transactionManager;

8.4 5주차 패턴 적용

5주차 패턴 적용:

  - 템플릿+전략:
    - 템플릿: TransactionTemplate (변하지 않음)
    - 전략: 람다 (변함)

  - 6주차 JdbcTemplate 와 같은 정신:
    - 자원 / 트랜잭션 자동
    - 비즈니스만

→ "5주차 패턴 += 적용"

8.5 설정

// TransactionTemplate 빈 설정
@Configuration
public class TransactionConfig {
    @Bean
    public TransactionTemplate transactionTemplate(
            PlatformTransactionManager tm) {
        TransactionTemplate template = new TransactionTemplate(tm);
        template.setIsolationLevel(TransactionDefinition.ISOLATION_READ_COMMITTED);
        template.setTimeout(30);
        return template;
    }
}
class TransactionTemplate {
    TransactionTemplate(PlatformTransactionManager tm) {}
    void setIsolationLevel(int i) {}
    void setTimeout(int t) {}
}
class PlatformTransactionManager {}
class TransactionDefinition { static int ISOLATION_READ_COMMITTED = 2; }
@interface Configuration {}
@interface Bean {}

8.6 vs @Transactional

TransactionTemplate vs @Transactional:

  TransactionTemplate:
    - 람다 (Callback)
    - 명시적
    - 메서드 안 일부에 한정 가능

  @Transactional:
    - 어노테이션 1줄
    - 자동
    - 메서드 전체

  실무 선택:
    - 90% @Transactional (간결)
    - 10% TransactionTemplate (세밀 제어)

8.7 ILIC 의 맥락

// ILIC 의 활용 (가끔)

@Service
public class ShipmentBatchService {
    @Autowired TransactionTemplate transactionTemplate;
    
    public void processBatch(List<Long> ids) {
        for (Long id : ids) {
            // 개별 트랜잭션 (실패해도 다른 거 계속)
            try {
                transactionTemplate.executeWithoutResult(status -> {
                    Shipment s = repo.findById(id).orElseThrow();
                    s.process();
                });
            } catch (Exception e) {
                log.error("Failed processing {}", id, e);
                // 다음 거 계속
            }
        }
    }
}

// 이런 케이스에 TransactionTemplate
// 메서드 전체가 트랜잭션 아닐 때

// 일반: @Transactional 표준 (Phase 7)
class Shipment { void process() {} }
ShipmentRepository repo;
interface ShipmentRepository { java.util.Optional<Shipment> findById(Long id); }
class TransactionTemplate {
    void executeWithoutResult(java.util.function.Consumer<TransactionStatus> c) {}
}
TransactionTemplate transactionTemplate;
class TransactionStatus {}
org.slf4j.Logger log;
@interface Service {}
@interface Autowired {}

8.8 자기 점검 답변

TransactionTemplate 의 활용은?

:
1. TransactionTemplate:

  • 람다 (Callback)
  1. 패턴:

    • 5주차 템플릿+전략
  2. vs @Transactional:

    • 명시적 vs 자동
  3. 실무:

    • 가끔 (세밀 제어)

9️⃣ Phase 6.2 예고 (3가지 구현체)

9.1 3가지 구현체

3가지 구현체 (Phase 6.2):

  1. DataSourceTransactionManager:
     - JDBC / JdbcTemplate
     - 6주차 학습 활용

  2. HibernateTransactionManager:
     - Hibernate 직접
     - 옛 스타일

  3. JpaTransactionManager:
     - JPA / Spring Data JPA
     - 현대 표준

9.2 선택 기준

선택 기준:

  사용 기술 → 구현체:

  JdbcTemplate 만 사용:
    → DataSourceTransactionManager

  Hibernate 직접 (JPA X):
    → HibernateTransactionManager
    (드묾)

  JPA / Spring Data JPA:
    → JpaTransactionManager

  Spring Boot:
    - 자동 선택
    - 의존성에 따라

9.3 6주차 ↔ 7주차

6주차 ↔ 7주차:

6주차 (DataSource):
  - DataSource 인터페이스
  - HikariDataSource 구현

7주차 (Transaction Manager):
  - PlatformTransactionManager 인터페이스
  - 3가지 구현체

같은 구조:
  - Application
      ↓ 인터페이스
    구현체

→ 5주차 디자인 패턴 일관 적용

9.4 Spring Boot 의 자동

Spring Boot 의 자동:

  spring-boot-starter-data-jpa:
    - JPA + Hibernate
    - JpaTransactionManager 자동

  spring-boot-starter-jdbc:
    - JDBC + JdbcTemplate
    - DataSourceTransactionManager 자동

  → 의존성만으로 결정

9.5 면접 단골 질문 매핑

Q핵심 답변
PlatformTransactionManager?Spring 트랜잭션 인터페이스
3 메서드?getTransaction/commit/rollback
DIP / OCP?인터페이스 의존
6주차 DataSource 와?같은 사상
TransactionDefinition?트랜잭션 설정
TransactionStatus?트랜잭션 상태
TransactionTemplate?람다 자동화
3 구현체?DS/Hibernate/JPA TM
Spring Boot?자동 선택
@Transactional?위에 어노테이션 (Phase 7)

9.6 자기 점검 체크리스트

정의

  • PlatformTransactionManager

추상화

  • 인터페이스

3 메서드

  • getTransaction/commit/rollback

DIP

  • 5주차 정신

DataSource 와

  • 같은 사상

OCP

  • 교체 가능

TransactionStatus / Definition

  • 의미

TransactionTemplate

  • 람다

Phase 6.2 예고

  • 3 구현체

9.7 추가 심화 질문

Q1: TransactionManager 인터페이스?

답:

  • PlatformTransactionManager 의 부모
  • 마커 인터페이스 (메서드 X)
  • ReactiveTransactionManager 등 다른 종류
  • 모두 TransactionManager 상속

Q2: ReactiveTransactionManager?

답:

  • 리액티브 트랜잭션 (R2DBC)
  • WebFlux 환경
  • Mono/Flux 반환
  • 별도 인터페이스

Q3: JTA (분산 트랜잭션)?

답:

  • Java Transaction API
  • 여러 DB / 메시지큐 트랜잭션
  • JtaTransactionManager
  • 복잡 / 성능 ↓

Q4: ChainedTransactionManager?

답:

  • 여러 TM 묶음
  • 순차 commit
  • 멀티 DB 환경
  • "최선 노력" (XA 아님)

Q5: TransactionSynchronization?

답:

  • 트랜잭션 콜백 등록
  • beforeCommit / afterCommit
  • @TransactionalEventListener 의 기반
  • 커스텀 처리

🎯 핵심 요약 — 3줄 정리

1. PlatformTransactionManager = Spring 트랜잭션 추상화

  • 인터페이스 + 3 메서드 (getTransaction / commit / rollback)
  • 5주차 DIP / OCP / DI 정신 + 6주차 DataSource 와 같은 구조
  • 자바 트랜잭션 추상화의 핵심

2. 인터페이스 의존의 가치

  • 애플리케이션 = 인터페이스만 의존 (구현체 모름)
  • 새 TM 추가 시 기존 코드 변경 X (OCP)
  • 테스트 / 마이그레이션 / 다중 DB 모두 안전

3. 추상화의 단계

  • PlatformTransactionManager (가장 저수준 추상)
  • TransactionTemplate (람다 자동화, 5주차 템플릿+전략)
  • @Transactional (어노테이션 + AOP/프록시, Phase 7 ★★★)
  • 점진적 자동화 → 5+6+7주차 응축

📚 다음으로...

Unit 6.2 — 3가지 구현체 (DataSource/Hibernate/JPA TM)

이번 Unit에서 인터페이스를 봤다면, 다음은 3가지 구현체 상세.

  • DataSourceTransactionManager (JDBC)
  • HibernateTransactionManager (Hibernate)
  • JpaTransactionManager (JPA)
  • Spring Boot 자동 선택

Phase 6 진행 상황

🎯 Phase 6 — PlatformTransactionManager
  ✅ Unit 6.1 인터페이스 추상화 ← 여기
  ⏭ Unit 6.2 3가지 구현체
  ⏭ Unit 6.3 사용 전후 비교

7주차 누적 진행

🗂️ Part A — 데이터 모델링과 ORM (완주)
  ✅ Phase 1-4 (16)

🔄 Part B — 트랜잭션 추상화의 진화
  ✅ Phase 5 (2)
  🎯 Phase 6 (1/3)

총: 19/24 Unit (79%)

🎯 Phase 6 시작 — Spring 의 트랜잭션 추상화

profile
Software Developer

0개의 댓글