89 lines
9.6 KiB
Markdown
89 lines
9.6 KiB
Markdown
---
|
|
title: "official-doc / Spring Framework — Transaction Propagation (REQUIRES_NEW · NESTED)"
|
|
source_type: official-doc
|
|
url: https://docs.spring.io/spring-framework/reference/data-access/transaction/declarative/tx-propagation.html
|
|
archive_url:
|
|
related_branches: [feature-application-port-usecase-contract]
|
|
related_projects: [ca-skeleton]
|
|
tags: [official-doc, ca-skeleton, persistence, spring-boot, transaction]
|
|
status: raw
|
|
confidence: high
|
|
created: 2026-05-28
|
|
---
|
|
|
|
# official-doc / Spring Framework — Transaction Propagation (REQUIRES_NEW · NESTED)
|
|
|
|
> Layer: `raw/official-docs/` — Spring Framework 공식 레퍼런스의 transaction propagation 섹션 원문 발췌.
|
|
> `PROPAGATION_REQUIRES_NEW` 의 independent physical transaction 보장 + connection pool 위험 + `PROPAGATION_NESTED` 의 savepoint 동작을 verbatim quote 로 보존.
|
|
|
|
## Parent / 활용 branch
|
|
|
|
| Branch | 이 자료가 정당화하는 결정 |
|
|
|---|---|
|
|
| [[raw/branch-notes/feature-application-port-usecase-contract]] | `TransactionPort.inNew` (PROPAGATION_REQUIRES_NEW) 의 independent physical transaction 보장 및 connection pool exhaustion / deadlock 위험 명시 근거. 기존 `spring-tx-management-reference.md` 는 REQUIRES_NEW 의 connection 동작을 직접 인용하지 않아 본 문서로 보강. |
|
|
|
|
## 출처 / Source
|
|
|
|
- 원본 URL: https://docs.spring.io/spring-framework/reference/data-access/transaction/declarative/tx-propagation.html
|
|
- 아카이브 URL: (미수집)
|
|
- 저자 / 조직: Spring Framework 프로젝트 (Pivotal / VMware / Broadcom)
|
|
- 발행일: 공식 레퍼런스 (버전 지속 갱신)
|
|
- 마지막 확인일: 2026-05-28
|
|
|
|
## 왜 저장했는지 / Why archived
|
|
|
|
`TransactionPort.inNew` 는 Spring `PROPAGATION_REQUIRES_NEW` 를 wrapping 하며, 이 propagation 이 **독립적인 물리 커넥션을 획득**하고 pool exhaustion / deadlock 위험을 수반한다는 사실을 공식 벤더 문서 verbatim 으로 증명할 필요가 있었다. `spring-tx-management-reference.md` 가 propagation 기본값과 readOnly 를 다루지만 REQUIRES_NEW 의 connection 동작을 직접 인용하지 않으므로 본 섹션을 별도 raw 자료로 분리 보관한다.
|
|
|
|
## 핵심 인용 / Key quotes (verbatim, 5개 — Self-Grep 전량 통과)
|
|
|
|
> [§Understanding PROPAGATION_REQUIRES_NEW] "PROPAGATION_REQUIRES_NEW, in contrast to PROPAGATION_REQUIRED, always uses an independent physical transaction for each affected transaction scope, never participating in an existing transaction for an outer scope."
|
|
|
|
> [§Understanding PROPAGATION_REQUIRES_NEW] "The resources attached to the outer transaction will remain bound there while the inner transaction acquires its own resources such as a new database connection."
|
|
|
|
> [§Understanding PROPAGATION_REQUIRES_NEW] "This may lead to exhaustion of the connection pool and potentially to a deadlock if several threads have an active outer transaction and wait to acquire a new connection for their inner transaction, with the pool not being able to hand out any such inner connection anymore."
|
|
|
|
> [§Understanding PROPAGATION_REQUIRES_NEW] "Do not use PROPAGATION_REQUIRES_NEW unless your connection pool is appropriately sized, exceeding the number of concurrent threads by at least 1."
|
|
|
|
> [§Understanding PROPAGATION_NESTED] "PROPAGATION_NESTED uses a single physical transaction with multiple savepoints that it can roll back to."
|
|
|
|
## Claims Extracted / 추출된 주장
|
|
|
|
> 이 자료가 직접 말하는 것만 claim 으로 분리한다.
|
|
|
|
| Claim ID | Claim (이 자료가 직접 말하는 것) | Evidence quote | Strength | Applies to | Does not prove |
|
|
|---|---|---|---|---|---|
|
|
| SPRING-PROP-C1 | PROPAGATION_REQUIRES_NEW 는 항상 독립적인 물리 트랜잭션을 사용하며 외부 scope 의 기존 트랜잭션에 참여하지 않는다 | [§Understanding PROPAGATION_REQUIRES_NEW] "PROPAGATION_REQUIRES_NEW, in contrast to PROPAGATION_REQUIRED, always uses an independent physical transaction for each affected transaction scope, never participating in an existing transaction for an outer scope." | `official-vendor-doc` | Spring Framework 의 `PROPAGATION_REQUIRES_NEW` 를 사용하는 모든 `@Transactional` 또는 `TransactionTemplate` 호출 | 특정 DB 드라이버·커넥션 풀 구현(HikariCP 등)에서의 구체 동작 보장. ca-tmpl `TransactionPort.inNew` 가 실제로 이 propagation 을 사용함을 단독 증명하지 않음 |
|
|
| SPRING-PROP-C2 | REQUIRES_NEW 내부 트랜잭션이 신규 DB 커넥션을 획득하는 동안 외부 트랜잭션의 리소스는 기존 커넥션에 bound 상태를 유지한다 | [§Understanding PROPAGATION_REQUIRES_NEW] "The resources attached to the outer transaction will remain bound there while the inner transaction acquires its own resources such as a new database connection." | `official-vendor-doc` | REQUIRES_NEW 가 외부 트랜잭션 컨텍스트 내에서 호출될 때 | HikariCP 의 실제 pool-size 임계값이나 타임아웃 동작 세부. `TransactionPort.inNew` 의 ca-tmpl 구현 레벨 검증 |
|
|
| SPRING-PROP-C3 | 여러 스레드가 활성 외부 트랜잭션을 보유한 채 내부 트랜잭션용 신규 커넥션을 대기하면 connection pool exhaustion 및 deadlock 이 발생할 수 있다 | [§Understanding PROPAGATION_REQUIRES_NEW] "This may lead to exhaustion of the connection pool and potentially to a deadlock if several threads have an active outer transaction and wait to acquire a new connection for their inner transaction, with the pool not being able to hand out any such inner connection anymore." | `official-vendor-doc` | REQUIRES_NEW 를 동시 다수 스레드가 사용하는 환경 | deadlock 이 반드시 발생한다는 보장. ca-tmpl 특정 pool size 에서의 실제 임계값 |
|
|
| SPRING-PROP-C4 | connection pool 크기가 동시 스레드 수보다 최소 1 이상 크지 않으면 PROPAGATION_REQUIRES_NEW 사용 금지 | [§Understanding PROPAGATION_REQUIRES_NEW] "Do not use PROPAGATION_REQUIRES_NEW unless your connection pool is appropriately sized, exceeding the number of concurrent threads by at least 1." | `official-vendor-doc` | REQUIRES_NEW 를 사용하는 모든 Spring 애플리케이션 | pool size 최솟값의 절대 수치 (동시 스레드 수는 애플리케이션별로 다름). HikariCP `maximumPoolSize` 의 구체 설정값 권고 |
|
|
| SPRING-PROP-C5 | PROPAGATION_NESTED 는 단일 물리 트랜잭션 내에 다수의 savepoint 를 사용하며 내부 scope 을 그 savepoint 까지 rollback 할 수 있다 | [§Understanding PROPAGATION_NESTED] "PROPAGATION_NESTED uses a single physical transaction with multiple savepoints that it can roll back to." | `official-vendor-doc` | JDBC savepoint 를 지원하는 드라이버 + `DataSourceTransactionManager` 사용 환경 | JPA / Hibernate 환경에서 NESTED 의 동작. `TransactionPort` 에서 NESTED 를 노출하지 않기로 한 ca-tmpl 결정 자체 (그것은 ca-tmpl 자체 계약) |
|
|
|
|
## Usage Boundaries / 적용 경계
|
|
|
|
- 이 자료가 직접 증명하는 것:
|
|
- `SPRING-PROP-C1`: Spring `PROPAGATION_REQUIRES_NEW` 가 독립적 물리 트랜잭션을 사용함
|
|
- `SPRING-PROP-C2`: 내부 REQUIRES_NEW 가 신규 커넥션을 필요로 하며 외부 커넥션은 점유 상태를 유지함
|
|
- `SPRING-PROP-C3`: 동시 다중 스레드 환경에서 pool exhaustion / deadlock 위험이 공식 문서에서 명시됨
|
|
- `SPRING-PROP-C4`: pool size ≥ (동시 스레드 수 + 1) 이라는 Spring 공식 최소 요건
|
|
- `SPRING-PROP-C5`: NESTED 가 savepoint 기반 단일 물리 트랜잭션임
|
|
- 이 자료가 증명하지 않는 것:
|
|
- ca-tmpl `SpringTransactionPort.inNew` 의 실제 REQUIRES_NEW propagation 설정이 올바름 (코드 레벨 검증은 별도)
|
|
- HikariCP 또는 다른 pool 구현에서의 실제 timeout / deadlock 임계값
|
|
- `NESTED` 가 JPA EntityManager 환경에서 작동함 (JDBC `DataSourceTransactionManager` 전용)
|
|
- `TransactionPort` 에서 `inNew` 를 노출하고 `NESTED` 를 숨긴 ca-tmpl 결정 자체의 정당성
|
|
- 내 프로젝트에 적용하려면 추가 확인이 필요한 것:
|
|
- ca-tmpl HikariCP `maximumPoolSize` 가 SPRING-PROP-C4 조건을 만족하는지 (pool size ≥ concurrent threads + 1) 측정 필요
|
|
- outbox/audit row 패턴에서 `inNew` 를 실제 호출하는 통합 테스트 (`feature-domain-event-outbox-contract` 단계)
|
|
|
|
## 메모 / Notes
|
|
|
|
- REQUIRES_NEW 의 deadlock 경고(SPRING-PROP-C3/C4)는 Spring 공식 문서가 **명시적 "Do not use … unless"** 형태로 사용 제한을 걸고 있다. ca-tmpl 이 `inNew` 를 TransactionPort API 에 노출했으므로, pool size 설정 가이드라인이 `feature-domain-event-outbox-contract` 또는 infrastructure 설정 branch 에서 별도 관리되어야 한다.
|
|
- PROPAGATION_NESTED 는 `JDBC savepoint + DataSourceTransactionManager` 전용이라는 제약이 공식 문서에 명시됨. ca-tmpl 이 NESTED 를 `TransactionPort` API 에서 노출하지 않기로 한 결정(2026-05-28)은 이 제약과 일관성이 있으나, 그 결정 자체는 이 자료가 아닌 ca-tmpl 자체 계약에서 온다.
|
|
- 이 페이지에서 PROPAGATION_REQUIRED 섹션도 다루지만 해당 내용은 `spring-tx-management-reference.md` 에서 이미 인용 중이므로 중복 claim 생성 안 함.
|
|
|
|
## Related / 관련
|
|
|
|
- [[raw/official-docs/spring-tx-management-reference]] — Spring transaction abstraction (`PlatformTransactionManager` SPI) + propagation 기본값 + readOnly. REQUIRES_NEW connection 동작은 본 문서가 보강.
|
|
- [[raw/official-docs/transaction-template-spring-official]] — `TransactionTemplate` programmatic API. `SpringTransactionPort` 의 구현 방식 근거.
|
|
- [[raw/official-docs/at-transactional-spring-official]] — `@Transactional` 선언적 API + self-invocation 함정.
|