토리맘의 한글라이즈 프로젝트 logo 토리맘의 한글라이즈 프로젝트

스프링 프레임워크 데이터 액세스 공식 레퍼런스를 한글로 번역한 문서입니다.

전체 목차는 여기에 있습니다.

스프링 프레임워크의 문서 챕터를 그대로 유지하긴 했지만, 이번 챕터는 제목과는 달리 R2DBC에서 자동 생성된 컬럼을 가져오는 법과 데이터베이스 커넥션을 생성하고 제어할 수 있는 방법을 소개하고 있습니다.

JDBC에 해당하는 내용은 자동 생성 키는 여기에서, 데이터베이스 커넥션 관리는 여기에서 소개하고 있습니다.

목차


auto-increment나 다른 식별용 컬럼을 정의하는 테이블에 row를 삽입하면 INSERT 문에서 키를 생성하기도 한다. StatementFilterFunction을 등록해서 원하는 컬럼에 생성된 키를 요청하면, 키를 생성한 컬럼 명을 직접 제어할 수 있다.

java kotlin
Mono<Integer> generatedId = client.sql("INSERT INTO table (name, state) VALUES(:name, :state)")
    .filter(statement -> statement.returnGeneratedValues("id"))
        .map(row -> row.get("id", Integer.class))
        .first();

// generatedId emits the generated key once the INSERT statement has finished
val generatedId = client.sql("INSERT INTO table (name, state) VALUES(:name, :state)")
    .filter { statement -> statement.returnGeneratedValues("id") }
        .map { row -> row.get("id", Integer.class) }
        .awaitOne()

// generatedId emits the generated key once the INSERT statement has finished

5.1. Controlling Database Connections

이번 섹션에서 다루는 내용은 다음과 같다:

5.1.1. Using ConnectionFactory

스프링은 ConnectionFactory를 통해서 데이터베이스에 대한 R2DBC 커넥션을 획득한다. ConnectionFactory는 R2DBC 스펙 중 하나로, 모든 드라이버의 공통 진입점이다. 덕분에 컨테이너나 프레임워크가 어플리케이션 코드에선 모르게 커넥션 풀링과 트랜잭션 관리 이슈를 처리할 수 있다. 개발자는 데이터베이스에 연결하는 방법에 대해 자세히는 몰라도 된다. 데이터베이스 연결은 ConnectionFactory를 세팅하는 관리자의 책임이다. 개발과 테스트 코드를 모두 맡았을 가능성이 높지만, 프로덕션 커넥션 팩토리를 설정하는 방법을 반드시 알아야 하는 건 아니다.

스프링의 R2DBC 레이어를 사용하면 제 3자가 제공하는 커넥션 풀 구현체로 자체 설정을 만들 수 있다. 보통은 R2DBC 풀(r2dbc-pool)을 많이 사용한다. 스프링이 배포하는 구현체는 테스트 전용이며 풀링을 제공하지 않는다.

ConnectionFactory를 설정하려면:

  1. 평소 R2DBC 커넥션을 획득할 때와 동일하게, ConnectionFactory로 커넥션을 가져와라.
  2. R2DBC URL을 제공해라 (정확한 URL은 사용하는 드라이버 문서를 확인해봐라).

다음은 ConnectionFactory를 설정하는 예시다:

java kotlin
ConnectionFactory factory = ConnectionFactories.get("r2dbc:h2:mem:///test?options=DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE");
val factory = ConnectionFactories.get("r2dbc:h2:mem:///test?options=DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE");

5.1.2. Using ConnectionFactoryUtils

ConnectionFactoryUtils 클래스는 ConnectionFactory에서 커넥션을 얻고, 필요하면 커넥션을 닫을 수 있는 static 메소드를 제공하는 간편하면서도 강력한 헬퍼 클래스다.

예를 들어 R2dbcTransactionManager에 구독자 Context에 바인딩한 커넥션을 제공한다.

5.1.3. Using SingleConnectionFactory

SingleConnectionFactory 클래스는 DelegatingConnectionFactory 인터페이스 구현체로, 사용 후에도 닫지 않는 단일 Connection을 래핑한다.

커넥션 풀을 가정하고 close를 호출하는 코드가 있다면 (persistence 툴을 사용할 때 처럼) suppressClose 속성을 true로 설정해야 한다. 이 설정은 물리적인 커넥션을 래핑해 close를 억제하는 프록시를 만든다. 단, 이렇게 설정하고 나면 더 이상 커넥션을 네이티브 Connection이나 다른 유사한 객체로 캐스팅할 수 없다.

SingleConnectionFactory는 일차적으로는 테스트 클래스이며, R2DBC 드라이버가 SingleConnectionFactory를 허용한다면 파이프라이닝같은 특정 요구 사항에 적용할 수도 있다. 커넥션 풀을 지원하는 ConnectionFactory와는 달리 SingleConnectionFactory는 항상 동일한 커넥션을 재사용하므로, 물리적인 커넥션을 과도하게 생성하지 않도록 방지해준다.

5.1.4. Using TransactionAwareConnectionFactoryProxy

TransactionAwareConnectionFactoryProxyConnectionFactory를 타겟으로 하는 프록시다. 이 프록시는 타겟 ConnectionFactory를 래핑해 스프링이 관리하는 트랜잭션을 인식할 수 있게 해준다.

스프링의 R2DBC 기능과 통합되지 않은 R2DBC 클라이언트를 사용하려면 이 클래스가 필요하다. 프록시를 사용하면 R2DBC 클라이언트를 사용하면서, 동시에 R2DBC 클라이언트가 스프링이 관리하는 트랜잭션에 참여하도록 만들 수 있다. 보통은 R2DBC 클라이언트도 ConnectionFactoryUtils로 리소스에 접근하도록 통합하는 게 리소스 관리 측면에서 좋다.

자세한 내용은 TransactionAwareConnectionFactoryProxy javadoc을 참고해라.

5.1.5. Using R2dbcTransactionManager

R2dbcTransactionManager 클래스는 단일 R2DBC 커넥션 팩토리를 사용하는 ReactiveTransactionManager 구현체다. 지정한 커넥션 팩토리의 R2DBC 커넥션을 구독자 Context로 바인딩하므로, 커넥션 팩토리 당 하나의 구독자 커넥션만 허용하는 것도 가능하다.

어플리케이션 코드에선 R2DBC의 표준 ConnectionFactory.create()가 아닌 ConnectionFactoryUtils.getConnection(ConnectionFactory)로 R2DBC 커넥션을 가져와야 한다.

모든 프레임워크 클래스(DatabaseClient 등)는 암묵적으로 ConnectionFactoryUtils.getConnection(ConnectionFactory)로 커넥션을 조회한다. R2dbcTransactionManager를 사용하지 않으면 ConnectionFactoryUtils.getConnection(ConnectionFactory)는 기존 표준 방식대로 커넥션을 조회한다. 따라서 ConnectionFactoryUtils는 어떤 상황에서도 사용할 수 있다.

R2dbcTransactionManager 클래스는 커넥션에 적용할 격리 수준 커스텀을 지원한다.


전체 목차는 여기에 있습니다.

<< >>