fix: 하네스 제거 및 keycloak 문서 보강

This commit is contained in:
DongHyeonka
2026-07-25 12:53:13 +09:00
parent 6c53ded9cb
commit d71669eb59
2329 changed files with 138239 additions and 172816 deletions
@@ -1 +0,0 @@
../../vault/20-evidence/official-docs/persistence-r2dbc-reactive-spring.md
@@ -0,0 +1,104 @@
---
title: R2DBC — Reactive Relational Database Connectivity (r2dbc.io + Spring Data R2DBC)
source_type: official-doc
status: raw
confidence: medium
url: https://r2dbc.io/
archive_url:
tags: [ca-persistence-failure, r2dbc, reactive, alternative, official-doc]
related_branches: [feature-persistence-failure-baseline]
related_projects: [ca-skeleton-operational-contract]
created: 2026-05-22
last_reviewed: 2026-05-27
---
# R2DBC — Reactive Relational Database Connectivity
> Layer: `raw/official-docs/` — R2DBC 공식 사이트 + Spring Data R2DBC reference 발췌. ca-tmpl persistence baseline 의 **반례 (대안 2)** — Hikari + JDBC blocking 결정의 alternative.
## Parent / 활용 branch (필수)
| Branch | 이 자료가 정당화하는 결정 |
|---|---|
| [[raw/branch-notes/feature-persistence-failure-baseline]] | "JPA + JDBC + Hikari blocking" baseline 결정의 alternative 비교 — R2DBC 가 어떤 trade-off 를 가지는지의 반례 |
특정 branch 없이 foundational 조사로 수집한 경우:
- [[raw/project-notes/ca-skeleton-operational-contract]] — ca-tmpl persistence stack 의 alternative 조사
## 컨텍스트 / 왜 저장했는지
ca-tmpl persistence baseline 의 **대안 후보**. "JPA + JDBC + Hikari blocking" 결정의 반례. R2DBC 를 택했을 때의 보안 / 운영 / debugging 차이를 비교 자료로 보관.
## 출처 / Source
- 원본 URL: https://r2dbc.io/
- 보조 URL: https://docs.spring.io/spring-data/relational/reference/r2dbc.html (Spring Data R2DBC reference 랜딩)
- 보조 URL: https://docs.spring.io/spring-data/relational/reference/r2dbc/transactionality.html (transactionality 페이지 — 404 응답, URL 후속 재확인 필요)
- 아카이브 URL: (미수집)
- 저자 / 조직: R2DBC 워킹 그룹 (Pivotal/VMware 주도, 다수 driver 벤더 참여); Spring Data R2DBC = Spring 공식
- 발행일: rolling (R2DBC 1.0 GA + Spring Data R2DBC 3.x current)
- 마지막 확인일: 2026-05-27 (WebFetch 검증: r2dbc.io 본문 verbatim 확보, Spring Data R2DBC reference 일부 verbatim 확보)
- 보조 자료: Oleh Dokuka, "Reactor 3 + R2DBC limitations" 발표 노트 (별도 raw 미수집)
## 핵심 인용 / Key quotes (verbatim)
> [r2dbc.io §In a Nutshell] "R2DBC is an open specification and establishes a Service Provider Interface (SPI) for driver vendors to implement and clients to consume."
> [r2dbc.io §Relational Meets Reactive] "R2DBC is a specification designed from the ground up for reactive programming with SQL databases."
> [r2dbc.io §Relational Meets Reactive] "It defines a non-blocking SPI for database driver implementors and client library authors."
> [Spring Data R2DBC reference §Connecting to a Relational Database — `AbstractR2dbcConfiguration`] "As compared to registering a `ConnectionFactory` instance directly, the configuration support has the added advantage of also providing the container with an `ExceptionTranslator` implementation that translates R2DBC exceptions to exceptions in Spring's portable `DataAccessException` hierarchy for data access classes annotated with the `@Repository` annotation."
## Claims Extracted / 추출된 주장
| Claim ID | Claim (이 자료가 직접 말하는 것) | Evidence quote | Strength | Applies to | Does not prove |
|---|---|---|---|---|---|
| R2DBC-C1 | R2DBC 는 open specification 이며, driver vendor 가 구현하고 client 가 consume 하는 SPI 정의 | [r2dbc.io §In a Nutshell] "R2DBC is an open specification and establishes a Service Provider Interface (SPI) for driver vendors to implement and clients to consume." | `official-standard` | SQL DB reactive driver 생태계 일반 | "JDBC 대체 표준" 같은 위계 비교 주장은 본 인용 범위 밖 — JDBC 와 공존 |
| R2DBC-C2 | R2DBC 는 reactive programming + SQL DB 를 위해 ground up 으로 설계 | [r2dbc.io §Relational Meets Reactive] "R2DBC is a specification designed from the ground up for reactive programming with SQL databases." | `official-standard` | reactive (Reactor / RxJava) + relational DB 사용 환경 | NoSQL 또는 messaging 시스템에 적용된다는 뜻 아님 |
| R2DBC-C3 | R2DBC 의 SPI 는 non-blocking 이며 driver implementor 와 client library 작성자 양쪽을 대상 | [r2dbc.io §Relational Meets Reactive] "It defines a non-blocking SPI for database driver implementors and client library authors." | `official-standard` | R2DBC driver / client library 구현 | "fully async at OS level" 같은 강한 주장은 본 인용 범위 밖 — SPI 가 non-blocking 이라는 것과 OS-level async 는 별개 |
| R2DBC-C4 | Spring Data R2DBC 는 `AbstractR2dbcConfiguration` 사용 시 `ExceptionTranslator` 를 컨테이너에 등록하여 R2DBC exception 을 Spring 의 portable `DataAccessException` hierarchy 로 변환 (`@Repository` 가 붙은 클래스 대상) | [Spring Data R2DBC reference] "...providing the container with an `ExceptionTranslator` implementation that translates R2DBC exceptions to exceptions in Spring's portable `DataAccessException` hierarchy for data access classes annotated with the `@Repository` annotation." | `official-vendor-doc` | Spring Data R2DBC + `@Repository` + `AbstractR2dbcConfiguration` 사용 시 | `R2dbcExceptionTranslator` 라는 정확한 클래스명이 본 인용에 등장하지 않음 — 구체 구현 클래스명은 javadoc 별도 확인 필요. 또한 `ConnectionFactory` 를 직접 등록하면 자동 적용되지 않음 (조건부) |
| R2DBC-C5 | R2DBC 는 JPA 를 지원하지 않으며, entity manager / lazy loading / first-level cache 가 없고 mapping 은 row-to-object 만 | (원본 frontmatter 발췌 — 본 세션 WebFetch 로 verbatim 직접 재확인 미완료. r2dbc.io 본문에 직접 등장하지 않음, Spring Data R2DBC reference 랜딩에도 등장하지 않음) | `needs-confirmation` | Spring Data R2DBC vs Spring Data JPA 비교 | 본 세션에서 직접 verbatim source 미확보 — 후속 라운드에 Spring Data R2DBC 의 "What is R2DBC" 또는 비교 페이지에서 verbatim 재확인 필요 |
| R2DBC-C6 | Transaction context 는 `ThreadLocal` 이 아닌 `reactor.util.context.Context` 로 전파되며, `@Transactional``TransactionalOperator` / reactive transaction manager 를 통해 동작 | (원본 frontmatter 발췌 — 본 세션에서 transactionality 페이지 404. r2dbc.io 와 Spring Data R2DBC 랜딩에는 등장하지 않음) | `needs-confirmation` | reactive Spring + `@Transactional` 사용 환경 | 본 세션 WebFetch 로 verbatim 미확보 — Spring Framework reference 의 transaction propagation 섹션 또는 Spring Data R2DBC transactionality 페이지의 정확한 URL 후속 확인 필요 |
## Usage Boundaries / 적용 경계
- **이 자료가 직접 증명하는 것**:
- `R2DBC-C1` ~ `C3`: R2DBC 가 reactive SQL DB 를 위한 non-blocking SPI 의 open specification 이라는 사실 (r2dbc.io 공식)
- `R2DBC-C4`: Spring Data R2DBC 가 `DataAccessException` hierarchy 로 exception 을 변환한다는 사실 → ca-tmpl 의 SQLState matrix 가 R2DBC 환경에서도 일부 재사용 가능
- **이 자료가 증명하지 않는 것**:
- R2DBC 가 JDBC 보다 "더 빠르다" 또는 "더 적은 자원을 쓴다" 는 정량 주장 (specific 워크로드 의존, 본 자료 범위 밖)
- JPA 와의 정확한 feature gap (`R2DBC-C5` 의 entity manager / lazy loading 부재 주장은 본 세션에서 verbatim 미확보 — `needs-confirmation`)
- reactive transaction propagation 의 정확한 메커니즘 (`R2DBC-C6``needs-confirmation`)
- Hikari `getThreadsAwaitingConnection()` 와 동등한 R2DBC pool metric 이름 (`r2dbc.pool.acquired` 등) — 별도 자료 (R2DBC Pool 또는 Micrometer 통합 문서) 필요
- **내 프로젝트에 적용하려면 추가 확인이 필요한 것**:
- ca-tmpl 이 실제로 R2DBC 를 고려할 워크로드인지 (high-fan-in API gateway 시나리오 여부)
- Flyway/Liquibase 등 blocking migration 도구와의 thread 정책 분리 절차
- reactive stack 도입 시 onboarding 비용 (stack trace 가 reactor operator chain 형태)
- `R2DBC-C5` / `C6` 의 verbatim 출처 후속 확보
## 메모 / Notes (내 프로젝트 해석 — 검증 전 추론)
> 본 섹션은 자료 직접 인용 아님. ca-tmpl 결정 컨텍스트 해석.
- **장점 (해석)**:
- connection 개수 << thread 개수. high-fan-in API gateway 에서 Hikari + JPA 보다 자원 효율 (정성적)
- backpressure: stream 결과를 lazy 하게 가져옴
- **단점 (ca-tmpl 입장 — 해석)**:
- JPA 생태계 손실 — `@OneToMany`, lazy loading, dirty checking, criteria, JPQL 없음. native query + manual mapping 이 기본 (`R2DBC-C5` — 단, verbatim 후속 확인 필요)
- **debugging cost** — stack trace 가 reactor operator chain. 신입/주니어 onboarding 부담
- blocking JDBC libraries (Flyway/Liquibase migration, JdbcTemplate) 와 혼용 시 thread 정책 분리 필요
- exception hierarchy 는 동일(`DataAccessException`)이라 SQLState matrix 재사용 가능 (`R2DBC-C4`) — 하지만 timeout 정책이 reactor `timeout()` operator 로 이동
- **시사점**: ca-tmpl 이 **JPA + JDBC blocking 을 baseline 으로 둔 이유** 의 반대편. high-throughput / low-resource API 에서만 정당화. dirty checking 의존도가 높은 도메인이면 도입 비용이 큼.
- **운영 차이 (해석, 별도 metric 자료 필요)**: Hikari `getThreadsAwaitingConnection()` 대신 connection factory 별 `r2dbc.pool.acquired`, `r2dbc.pool.pending`, `r2dbc.pool.max.allocated` metric 후보 — R2DBC Pool 문서 별도 확인 필요.
## Related / 관련
- 같은 주제 다른 official-doc / company-tech-blog:
- [[raw/official-docs/persistence-spring-dataaccessexception-hierarchy]] (`DataAccessException` hierarchy — R2DBC 와 공유)
- [[raw/official-docs/persistence-hikaricp-pool-sizing-wiki]] (blocking JDBC alternative)
- 인용하는 branch:
- [[raw/branch-notes/feature-persistence-failure-baseline]]
- 인용하는 wiki: (미작성)
- 대안 그룹 (ca-tmpl 결정 컨텍스트): **Group G-C — Persistence failure** (대안 1: Spring Data JPA blocking [ca-tmpl 채택] / 대안 2: R2DBC reactive / 대안 3: JOOQ SQL-first / 대안 4: 직접 JDBC + 자체 classifier)