104 lines
11 KiB
Markdown
104 lines
11 KiB
Markdown
---
|
|
title: "Using @Transactional :: Spring Framework Reference"
|
|
source_type: official-doc
|
|
url: https://docs.spring.io/spring-framework/reference/data-access/transaction/declarative/annotations.html
|
|
archive_url:
|
|
status: raw
|
|
confidence: high
|
|
tags: [ca-transaction-boundary, at-transactional, spring-official, transaction-management, declarative-tx]
|
|
related_projects: [ca-skeleton-operational-contract]
|
|
related_branches: [feature-application-port-usecase-contract, feature-transaction-concurrency-contract]
|
|
created: 2026-05-22
|
|
last_reviewed: 2026-05-27
|
|
---
|
|
|
|
# Using @Transactional :: Spring Framework Reference
|
|
|
|
> Layer: `raw/official-docs/` — Spring Framework 7.x reference, `data-access/transaction/declarative/annotations` 섹션 verbatim 발췌.
|
|
> ca-tmpl TransactionPort 결정의 baseline 대안 (`@Transactional` 직접 application service 부착 패턴) 의 1차 근거.
|
|
|
|
## Parent / 활용 branch (필수)
|
|
|
|
| Branch | 이 자료가 정당화하는 결정 |
|
|
|---|---|
|
|
| [[raw/branch-notes/feature-application-port-usecase-contract]] | application layer 가 `org.springframework.transaction.annotation.Transactional` 을 import 하면 clean/hexagonal architecture dependency rule 위반이라는 결정 근거 (Spring 공식 권장 패턴을 정확히 식별) |
|
|
| [[raw/branch-notes/feature-transaction-concurrency-contract]] | Topic 2 — Transaction Boundary 대안 1 (`@Transactional` direct) 의 공식 정의·활성화 요구사항·self-invocation 함정 비교 baseline |
|
|
|
|
## 컨텍스트
|
|
|
|
ca-tmpl 의 TransactionPort 결정에 대한 대안 1: **`@Transactional` 직접 application service 에 부착**. Spring 공식이 권장하는 가장 흔한 패턴이며, ca-tmpl 이 forbidden 처리한 대상이므로 baseline 비교용 원문이 필요.
|
|
|
|
## 출처 / Source
|
|
|
|
- 원본 URL: https://docs.spring.io/spring-framework/reference/data-access/transaction/declarative/annotations.html
|
|
- 아카이브 URL: (미수집)
|
|
- 저자 / 조직: Spring Framework / VMware (Broadcom)
|
|
- 발행일: Spring Framework 7.x reference (current, rolling docs)
|
|
- 마지막 확인일: 2026-05-27
|
|
|
|
## 핵심 인용 / Key quotes (verbatim)
|
|
|
|
> [§Using @Transactional] "The Spring team recommends that you annotate methods of concrete classes with the `@Transactional` annotation, rather than relying on annotated methods in interfaces, even if the latter does work for interface-based and target-class proxies as of 5.0."
|
|
|
|
> [§Using @Transactional] "Since Java annotations are not inherited from interfaces, interface-declared annotations are still not recognized by the weaving infrastructure when using AspectJ mode, so the aspect does not get applied. As a consequence, your transaction annotations may be silently ignored: Your code might appear to 'work' until you test a rollback scenario."
|
|
|
|
> [§Using @Transactional] "However, the mere presence of the `@Transactional` annotation is not enough to activate the transactional behavior. The `@Transactional` annotation is merely metadata that can be consumed by corresponding runtime infrastructure which uses that metadata to configure the appropriate beans with transactional behavior."
|
|
|
|
> [§Using @Transactional] "In the preceding examples that use programmatic configuration, the `@EnableTransactionManagement` annotation switches on actual transaction management at runtime."
|
|
|
|
> [§Method visibility and @Transactional in proxy mode] "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`."
|
|
|
|
> [§Method visibility and @Transactional in proxy mode] "Consider using AspectJ mode (see the `mode` attribute in the following table) if you expect self-invocations to be wrapped with transactions as well."
|
|
|
|
## Claims Extracted / 추출된 주장
|
|
|
|
| Claim ID | Claim (이 자료가 직접 말하는 것) | Evidence quote | Strength | Applies to | Does not prove |
|
|
|---|---|---|---|---|---|
|
|
| AT-TX-C1 | Spring 팀은 인터페이스가 아닌 **concrete class 의 메서드**에 `@Transactional` 을 부착하도록 권장 (interface-based/target-class proxy 가 5.0부터 동작은 하지만 권장 아님) | [§Using @Transactional] "The Spring team recommends that you annotate methods of concrete classes with the `@Transactional` annotation, rather than relying on annotated methods in interfaces..." | `official-vendor-doc` | Spring Framework 5.0+ `@Transactional` 사용 시 | concrete class 부착이 self-invocation 함정도 해결한다는 뜻은 아님 (별도 항목, AT-TX-C5) |
|
|
| AT-TX-C2 | **AspectJ mode** 에서는 interface 에 부착된 `@Transactional` 이 weaving infrastructure 에 인식되지 않아 **silently 무시**될 수 있음 — rollback 시나리오 테스트 전까지 정상 동작처럼 보임 | [§Using @Transactional] "...interface-declared annotations are still not recognized by the weaving infrastructure when using AspectJ mode... your transaction annotations may be silently ignored: Your code might appear to 'work' until you test a rollback scenario." | `official-vendor-doc` | AspectJ mode + interface 에 `@Transactional` 부착한 경우 | proxy mode (기본값) 에서도 동일하게 무시된다는 뜻은 아님 (proxy mode 는 interface-based proxy 에서 인식 가능) |
|
|
| AT-TX-C3 | `@Transactional` 어노테이션의 **단순 존재만으로는** transactional behavior 가 활성화되지 않음 — 어노테이션은 **메타데이터**일 뿐, runtime infrastructure 가 이 메타데이터를 소비해야 함 | [§Using @Transactional] "However, the mere presence of the `@Transactional` annotation is not enough to activate the transactional behavior. The `@Transactional` annotation is merely metadata..." | `official-vendor-doc` | 모든 Spring `@Transactional` 사용 시 | 메타데이터 자체가 무가치하다는 뜻은 아님 — Spring Boot auto-config 환경에서는 활성화가 자동 (별도 항목) |
|
|
| AT-TX-C4 | **`@EnableTransactionManagement`** 어노테이션이 runtime 에서 실제 transaction management 를 활성화 (programmatic configuration 시) | [§Using @Transactional] "...the `@EnableTransactionManagement` annotation switches on actual transaction management at runtime." | `official-vendor-doc` | programmatic configuration (Java @Configuration) 사용 시 | XML `<tx:annotation-driven/>` 가 동등한 역할을 한다는 뜻을 본 인용에서 직접 확인할 수는 없음 (별도 페이지 필요) |
|
|
| AT-TX-C5 | proxy mode (기본값) 에서는 **self-invocation** (target object 내부 메서드 호출) 시 proxy 를 우회하므로 `@Transactional` 이 적용되지 않음 — AspectJ mode 사용을 고려하라는 공식 권고 | [§Method visibility and @Transactional in proxy mode] "...self-invocation... does not lead to an actual transaction at runtime even if the invoked method is marked with `@Transactional`." + "Consider using AspectJ mode... if you expect self-invocations to be wrapped with transactions as well." | `official-vendor-doc` | Spring proxy mode (default) | AspectJ mode 가 self-invocation 함정만 해결한다는 뜻은 아님 (interface annotation 함정은 별도, AT-TX-C2) |
|
|
|
|
## Usage Boundaries / 적용 경계
|
|
|
|
- **이 자료가 직접 증명하는 것**:
|
|
- `AT-TX-C1` ~ `C5`: Spring 공식의 `@Transactional` 사용 권장사항 (concrete class 부착), AspectJ mode 함정 (interface annotation silently ignored), 활성화 요건 (`@EnableTransactionManagement`), proxy mode 의 self-invocation 한계
|
|
- **이 자료가 증명하지 않는 것**:
|
|
- `@Transactional` 을 application service 에 직접 부착하는 것이 clean/hexagonal architecture 와 양립 가능하다 또는 불가능하다는 평가 (architecture-level 판단은 본 자료 범위 밖 — ca-tmpl 의 결정 근거는 별도 문서)
|
|
- `@Transactional` 의 propagation / isolation / rollbackFor / readOnly 속성의 상세 시맨틱 (같은 reference 의 다른 섹션에서 다룸, 본 raw 의 인용 범위 밖)
|
|
- Spring Boot auto-configuration 이 `@EnableTransactionManagement` 를 자동으로 활성화하는지 (Spring Boot 측 별도 문서 — 본 Spring Framework reference 에는 명시 없음)
|
|
- **내 프로젝트에 적용하려면 추가 확인이 필요한 것**:
|
|
- ca-tmpl 이 채택한 `TransactionPort` adapter 가 내부적으로 `@Transactional` 메서드를 호출할 때 self-invocation 함정에 걸리는지 (adapter Spring bean 외부 호출이라면 안전)
|
|
- AspectJ mode 사용 시 build pipeline (compile-time weaving) 추가 비용
|
|
|
|
## 메모 / Notes (내 프로젝트 해석)
|
|
|
|
> 본 섹션은 자료 직접 인용 아님. ca-tmpl 결정 컨텍스트 해석.
|
|
|
|
- 적용 시나리오: 단일 모듈 Spring Boot 앱, 클린 아키텍처를 엄격히 적용하지 않는 일반 서비스. 가장 검증되고 익숙한 옵션.
|
|
- 장점:
|
|
- 가장 적은 코드. 메서드에 어노테이션 1줄.
|
|
- propagation / isolation / rollbackFor / readOnly 등 모든 속성을 선언적으로 제어.
|
|
- Spring 진영 표준이라 신규 개발자 학습 비용 최저.
|
|
- 단점:
|
|
- **application service 가 `org.springframework.transaction.annotation.Transactional` 을 import 해야 함 → clean/hexagonal architecture 에서 dependency rule 위반.**
|
|
- self-invocation 은 proxy 를 거치지 않아 silently 무시됨 (AT-TX-C5).
|
|
- 인터페이스에 단 annotation 은 AspectJ mode 에서 무시될 수 있음 (AT-TX-C2 공식 경고).
|
|
- 테스트 시 트랜잭션 동작 검증은 Spring context 필요.
|
|
- ca-tmpl (TransactionPort) 와의 차이: 정확히 ca-tmpl 이 막은 패턴. application layer 에 Spring import 가 새는 것이 핵심 차이.
|
|
- testability 영향: ★ 하락 — 트랜잭션 boundary 자체를 검증하려면 `@SpringBootTest` 또는 `@DataJpaTest` 필요.
|
|
- code 복잡도 영향: 최저 (어노테이션 1줄). 단, framework lock-in 비용은 숨겨져 있음.
|
|
|
|
## Related / 관련
|
|
|
|
- 같은 주제 다른 official-doc:
|
|
- [[raw/official-docs/transaction-template-spring-official]] (대안 2: programmatic `TransactionTemplate`)
|
|
- 적용 ca-tmpl branch-note:
|
|
- [[raw/branch-notes/feature-application-port-usecase-contract]]
|
|
- [[raw/branch-notes/feature-transaction-concurrency-contract]]
|
|
- canonical contract 섹션:
|
|
- [[raw/project-notes/ca-skeleton-operational-contract]] (§14. Transaction / Concurrency Contract, §5. Exception Ownership Contract)
|
|
- 대안 그룹: **Topic 2 — Transaction Boundary** (5종: TransactionPort / @Transactional direct / TransactionTemplate / Functional monad / Custom AOP) — 본 source 는 **대안 1**.
|
|
- 인용한 wiki 요약: (미작성)
|