--- kind: CONCEPT slug: messaging-inbox-jdbc-postgresql-c06 title: 커넥션 조회가 새 커넥션을 열기 전에 검사가 돌아야 한다 topic: state-machines-and-ownership project: clean-architecture-backend-template status: 게시 전 sourceRevision: 21234e38cdb9a926cbc92bb97a2aee2e4a7d2916 rootTreeNode: concept:messaging-inbox-jdbc-postgresql-c06 evidenceCapturedOn: 2026-09-01 assets: - key: messaging-inbox-jdbc-postgresql-c06 file: ../../../final/evidence/rendered/messaging-inbox-jdbc-postgresql-c06.svg - key: messaging-inbox-jdbc-postgresql-c06-diagram file: ../../../final/assets/diagrams/messaging-inbox-jdbc-postgresql-c06.svg evidence: - ../../../final/evidence/raw/messaging-inbox-jdbc-postgresql-c06.txt source: - 원본 분석 절은 final/document.md#a19-messaging-inbox-jdbc-postgresql#L346 이다. module: messaging-inbox-jdbc-postgresql --- # 커넥션 조회가 새 커넥션을 열기 전에 검사가 돌아야 한다 `DataSourceUtils.getConnection`은 활성 트랜잭션에 묶인 커넥션이 있으면 그것을 주고 없으면 새로 연다. 그래서 `requireActiveTransaction`이 먼저 도는 것이 필수다. ## 관계 - **컬럼 폭은 애플리케이션 검증과 짝을 이룬다** 같은 분석 리프에서 끌어낸 규칙이다. - **같은 안전 규칙은 한 공식과 한 강제 시점을 갖는다** 같은 분석 리프에서 끌어낸 규칙이다. ## 본문 **이 leaf의 주제 자체가 트랜잭션이다.** `DataSourceUtils.getConnection`은 활성 트랜잭션에 묶인 커넥션이 있으면 그것을 주고, 없으면 새로 연다. ## 커넥션 조회보다 앞선 검사 :::evidence key="messaging-inbox-jdbc-postgresql-c06-diagram" alt="트랜잭션 검사와 커넥션 조회와 INSERT 가 왼쪽에서 오른쪽으로 이어지는 구조" caption="커넥션 조회보다 앞선 검사" zoom="false" ::: 그래서 `requireActiveTransaction`이 **먼저** 도는 것이 필수다 — 없으면 새 커넥션이 열리고 자동 커밋된다. 그것이 §4.1의 이전 결함이다. ## DataSourceUtils 참조 위치 :::evidence key="messaging-inbox-jdbc-postgresql-c06" alt="코드베이스에서 DataSourceUtils 를 검색한 출력 15줄. 이 기록이 세는 참조가 그 출력에 그대로 보인다." caption="DataSourceUtils 코드베이스 검색 — 15줄 · exit 0" zoom="true" ::: ## 트랜잭션에 참여하지 않는 세 메서드 `isProcessed`와 두 `purge*`는 `dataSource.getConnection()`을 직접 쓴다 — 트랜잭션에 참여하지 않는다. javadoc이 그것을 명시한다("The no-argument overload is provided only for retention sweeps and read-only queries"). ## 동시성 원시 요소가 DB에 있다 Java 쪽에 락이나 원자 변수가 없다. 수명주기 참여 없음 — `InboxCleanupJob`을 스케줄링하는 것은 starter다.