Files
llm-wiki/raw/official-docs/spring-tx-management-reference.md
T

120 lines
13 KiB
Markdown

---
title: Spring Framework — Transaction Management (@Transactional, PlatformTransactionManager, Propagation)
source_type: official-doc
url: https://docs.spring.io/spring-framework/reference/data-access/transaction.html
archive_url:
related_projects: []
related_branches: [feature-repository-access-permission-contract, feature-transaction-concurrency-contract, feature-application-port-usecase-contract]
tags: [spring-framework, spring-tx, transaction, declarative-tx, propagation, isolation, rollback, aop-proxy, platform-transaction-manager, official-doc]
status: raw
confidence: high
created: 2026-05-27
last_reviewed: 2026-05-27
---
# Spring Framework — Transaction Management (@Transactional, PlatformTransactionManager, Propagation)
> Layer: `raw/official-docs/` — Spring Framework Reference / "Transaction Management" 챕터 verbatim.
> Repository / Service 계층의 `@Transactional` 위치, propagation 선택, rollback 규칙, AOP self-invocation 함정의 1차 근거.
## Parent / 활용 branch (필수)
| Branch | 이 자료가 정당화하는 결정 |
|---|---|
| [[raw/branch-notes/feature-repository-access-permission-contract]] | D4 — Repository 메서드 직접 호출과 UseCase 경유의 트랜잭션 경계 차이. AOP proxy self-invocation 으로 `@Transactional` 이 우회될 수 있다는 사실을 근거로 "UseCase 만 `@Transactional` 보유" 규칙 채택 |
| [[raw/branch-notes/feature-transaction-concurrency-contract]] | `@Transactional` 의 default propagation REQUIRED / rollback 정책 / isolation 옵션의 공식 정의 |
| [[raw/branch-notes/feature-application-port-usecase-contract]] | UseCase (application port impl) 가 트랜잭션 경계 owner 라는 설계 결정의 공식 근거 — `PlatformTransactionManager` 는 SPI 이고 `@Transactional` 은 외부 호출에서만 발동 |
## 컨텍스트
ca-tmpl 계열 프로젝트의 Clean Architecture 레이어링에서 트랜잭션 경계는 UseCase (application layer) 에 둔다. 이 결정의 정당화는 다음 두 가지 공식 사실에 기반: (1) Spring 의 `@Transactional` 은 default 로 AOP proxy 기반이라 self-invocation 시 발동하지 않음, (2) propagation REQUIRED 가 default 이므로 UseCase 진입 후 호출되는 모든 Repository 메서드는 동일 트랜잭션을 공유. 본 자료는 두 사실을 verbatim 으로 보존하기 위한 raw.
## 출처 / Source
- 원본 URL: https://docs.spring.io/spring-framework/reference/data-access/transaction.html
- 보조 URL (sub-pages):
- https://docs.spring.io/spring-framework/reference/data-access/transaction/strategies.html (PlatformTransactionManager / TransactionDefinition / TransactionStatus)
- https://docs.spring.io/spring-framework/reference/data-access/transaction/declarative/annotations.html (`@Transactional` 속성 / proxy mode / rollback rules)
- 아카이브 URL: (미수집)
- 저자 / 조직: Spring Framework (VMware / Broadcom)
- 발행일: rolling docs (current = 6.x)
- 마지막 확인일: 2026-05-27
## 핵심 인용 / Key quotes (verbatim)
> [§Transaction Management - Introduction] "Comprehensive transaction support is among the most compelling reasons to use the Spring Framework."
> [§Transaction Management - Introduction] "A consistent programming model across different transaction APIs, such as Java Transaction API (JTA), JDBC, Hibernate, and the Java Persistence API (JPA)."
> [§Understanding the Spring Framework Transaction Abstraction] "The key to the Spring transaction abstraction is the notion of a transaction strategy. A transaction strategy is defined by a `TransactionManager`, specifically the `org.springframework.transaction.PlatformTransactionManager` interface for imperative transaction management and the `org.springframework.transaction.ReactiveTransactionManager` interface for reactive transaction management."
> [§Understanding the Spring Framework Transaction Abstraction - PlatformTransactionManager API] "This is primarily a service provider interface (SPI), although you can use it programmatically from your application code. Because `PlatformTransactionManager` is an interface, it can be easily mocked or stubbed as necessary."
> [§TransactionStatus Interface] "The `TransactionStatus` interface provides a simple way for transactional code to control transaction execution and query transaction status. The concepts should be familiar, as they are common to all transaction APIs."
> [§@Transactional Settings - Propagation] "The propagation setting is `PROPAGATION_REQUIRED.`"
> [§@Transactional Settings - Rollback Default] "Any `RuntimeException` or `Error` triggers rollback, and any checked `Exception` does not."
> [§@Transactional Settings - Rollback Attributes] "rollbackFor: Array of `Class` objects, which must be derived from `Throwable.` Optional array of exception types that must cause rollback."
> [§In proxy mode - Self-Invocation] "In proxy mode (which is the default), only external method calls coming in through the proxy are intercepted. This means that self-invocation (in effect, a method within the target object calling another method of the target object) does not lead to an actual transaction at runtime even if the invoked method is marked with `@Transactional`."
> [§@Transactional Settings - Isolation] "isolation: enum: `Isolation` - Optional isolation level. Applies only to propagation values of `REQUIRED` or `REQUIRES_NEW`."
> [§@Transactional Settings - ReadOnly] "readOnly: boolean - Read-write versus read-only transaction. Only applicable to values of `REQUIRED` or `REQUIRES_NEW`."
> [§@Transactional Settings - Timeout] "timeout: int (in seconds of granularity) - Optional transaction timeout. Applies only to propagation values of `REQUIRED` or `REQUIRES_NEW`."
## Claims Extracted / 추출된 주장
| Claim ID | Claim (이 자료가 직접 말하는 것) | Evidence quote | Strength | Applies to | Does not prove |
|---|---|---|---|---|---|
| SPRING-TX-MGR-C1 | Spring 의 transaction abstraction 은 JTA / JDBC / Hibernate / JPA 등 서로 다른 transaction API 위에 일관된 프로그래밍 모델을 제공한다 | [§Transaction Management - Introduction] "A consistent programming model across different transaction APIs, such as Java Transaction API (JTA), JDBC, Hibernate, and the Java Persistence API (JPA)." | `official-vendor-doc` | Spring Framework 6.x | 특정 ORM 별 미세한 동작 차이(예: JPA flush 시점)는 본 인용 범위 밖 |
| SPRING-TX-MGR-C2 | transaction strategy 는 `PlatformTransactionManager` interface (imperative) 또는 `ReactiveTransactionManager` (reactive) 로 정의된다. 이는 SPI 로, application code 에서 직접 사용도 가능하며 mock/stub 이 쉽다 | [§Understanding the Spring Framework Transaction Abstraction] "The key to the Spring transaction abstraction is the notion of a transaction strategy. A transaction strategy is defined by a `TransactionManager`, specifically the `org.springframework.transaction.PlatformTransactionManager` interface..." + [§PlatformTransactionManager API] "This is primarily a service provider interface (SPI)... `PlatformTransactionManager` is an interface, it can be easily mocked or stubbed as necessary." | `official-vendor-doc` | Spring Framework 6.x, imperative/reactive 모두 | 구체적 구현체(`DataSourceTransactionManager`, `JpaTransactionManager` 등) 의 동작 차이는 본 인용 범위 밖 |
| SPRING-TX-MGR-C3 | `@Transactional` 의 default propagation 은 `PROPAGATION_REQUIRED` 다 | [§@Transactional Settings - Propagation] "The propagation setting is `PROPAGATION_REQUIRED.`" | `official-vendor-doc` | `@Transactional` annotation 사용 시 (속성 미지정) | REQUIRES_NEW / NESTED / SUPPORTS 등 다른 propagation 의 정확한 시맨틱은 별도 페이지 참조 필요 |
| SPRING-TX-MGR-C4 | `@Transactional` 의 default rollback rule 은 "RuntimeException 또는 Error 면 rollback, checked Exception 은 rollback 하지 않음" 이다. `rollbackFor` / `noRollbackFor` 속성으로 override 가능 | [§@Transactional Settings - Rollback Default] "Any `RuntimeException` or `Error` triggers rollback, and any checked `Exception` does not." + [§Rollback Attributes] "rollbackFor: Array of `Class` objects, which must be derived from `Throwable.` Optional array of exception types that must cause rollback." | `official-vendor-doc` | `@Transactional` 속성 미지정 (default) | XML 기반 `<tx:advice>` 설정의 default 가 동일한지는 본 인용 범위 밖 |
| SPRING-TX-MGR-C5 | proxy mode 가 default 이고, proxy 를 거치지 않는 self-invocation (같은 target object 내부의 다른 메서드 호출) 은 `@Transactional` 이 붙어 있어도 실제 transaction 을 발동시키지 않는다 | [§In proxy mode - Self-Invocation] "In proxy mode (which is the default), only external method calls coming in through the proxy are intercepted. This means that self-invocation (in effect, a method within the target object calling another method of the target object) does not lead to an actual transaction at runtime even if the invoked method is marked with `@Transactional`." | `official-vendor-doc` | Spring AOP proxy mode (default), `@EnableTransactionManagement(mode = PROXY)` | AspectJ mode (`mode = ASPECTJ`) 에서도 동일하게 우회된다는 뜻은 **아님** — AspectJ 모드는 self-invocation 도 가로챔 |
| SPRING-TX-MGR-C6 | `@Transactional``isolation`, `readOnly`, `timeout` 속성은 propagation 값이 `REQUIRED` 또는 `REQUIRES_NEW` 일 때만 적용된다 | [§@Transactional Settings - Isolation] "isolation: ... Applies only to propagation values of `REQUIRED` or `REQUIRES_NEW`." + [§ReadOnly] "readOnly: ... Only applicable to values of `REQUIRED` or `REQUIRES_NEW`." + [§Timeout] "timeout: ... Applies only to propagation values of `REQUIRED` or `REQUIRES_NEW`." | `official-vendor-doc` | `@Transactional` annotation, propagation REQUIRED / REQUIRES_NEW | SUPPORTS / NOT_SUPPORTED / NESTED 등에서 isolation/readOnly/timeout 가 적용되는지는 본 인용 범위 밖 (적용 안 됨 시사) |
## Usage Boundaries / 적용 경계
- **이 자료가 직접 증명하는 것**:
- `SPRING-TX-MGR-C1`: Spring 이 JTA/JDBC/Hibernate/JPA 위에 통합 프로그래밍 모델 제공
- `SPRING-TX-MGR-C2`: `PlatformTransactionManager` 는 SPI; imperative 와 reactive 가 분리된 interface
- `SPRING-TX-MGR-C3`: `@Transactional` default propagation = REQUIRED
- `SPRING-TX-MGR-C4`: default rollback = unchecked exception 만 (checked 는 안 함); `rollbackFor` 로 override
- `SPRING-TX-MGR-C5`: proxy mode (default) 에서 self-invocation 은 `@Transactional` 우회
- `SPRING-TX-MGR-C6`: isolation/readOnly/timeout 은 REQUIRED/REQUIRES_NEW 한정
- **이 자료가 증명하지 않는 것**:
- 특정 DB (PostgreSQL, MySQL, Oracle) 별 isolation level 의 실제 잠금 동작
- JPA persistence context 의 flush/clear 시점이 `@Transactional` 경계와 정확히 어떻게 맞물리는지
- `@Transactional` 이 메서드 visibility (private, protected) 와 어떻게 상호작용하는지 — 별도 페이지에서 "public only" 명시
- "Repository 에 `@Transactional` 을 두면 안 된다" 는 베스트 프랙티스 — 본 페이지는 위치를 규정하지 않음
- propagation REQUIRES_NEW 가 별도 connection 을 사용하는지, 같은 connection 의 savepoint 인지의 정확한 동작
- **내 프로젝트에 적용하려면 추가 확인이 필요한 것**:
- ca-tmpl 의 UseCase 가 같은 클래스 안의 다른 UseCase 메서드를 호출하면 `@Transactional` 이 우회되는지 — `SPRING-TX-MGR-C5` 에 따라 우회됨, 별도 bean 분리 또는 self-injection 패턴 필요
- JPA `EntityManager.flush()` 가 application port impl 의 어느 시점에서 호출되는지 검증 (commit 시점 default)
- Repository (jOOQ / JPA) 메서드 직접 호출 시 트랜잭션 없이 동작하는지 — `@Transactional` 미존재 시 auto-commit 동작 검증
## 메모 / Notes
- 인용 1 해석 후보 (미검증):
- `SPRING-TX-MGR-C5` (self-invocation 우회) → ca-tmpl 의 "UseCase = port impl 1:1" 원칙은 이 함정을 자연 회피
- 추가로 봐야 할 동일 출처 페이지:
- `https://docs.spring.io/spring-framework/reference/data-access/transaction/declarative/tx-propagation.html` (propagation 시맨틱 상세)
- `https://docs.spring.io/spring-framework/reference/data-access/transaction/declarative/aspectj.html` (AspectJ mode 차이)
## Related / 관련
- 같은 주제 다른 official-doc:
- [[raw/official-docs/spring-smartlifecycle-reference]]
- [[raw/official-docs/spring-restclient-builder-reference]]
- 인용하는 branch:
- [[raw/branch-notes/feature-repository-access-permission-contract]]
- [[raw/branch-notes/feature-transaction-concurrency-contract]]
- [[raw/branch-notes/feature-application-port-usecase-contract]]
- 인용하는 project:
- [[raw/project-notes/ca-skeleton-operational-contract]]
- 인용하는 wiki: (미작성)