--- 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)