# r2dbc

DataAccessResourceFailureException 이슈 해결기
Situation > DataAccessResourceFailureException: Failed to obtain R2DBC Connection 정상적으로 데이터베이스에 연결이 된 상황 스프링 배치가 R2DBC를 통해서 쿼리를 정상적으로 호출하다가, 위의 예외가 발생 Analysis 배치 시스템 성능을 고도화하려고, 병렬 프로그래밍이 적용된 부분이 있었음 병렬 처리로 인해 커넥션 할당이 많아져, 데이터베이스에서 커넥션을 더 이상 할당해주지 못하는 상황으로 인지 TroubleShotting 매번 커넥션을 맺는 방식보다는, 일반 MYSQL처럼 커넥션 풀에서 커넥션을 재사용할 수 있도록 설정이 필요 R2DBC는 io.r2dbc.r2dbc-pool를 통해서, 커넥션 풀을 설정할 수 있었음 Dependency 추가 @Bean 추가 maxSize는 일반적으로 사용하는 10개를

[spring data R2DBC] JPA 사용하다가 R2DBC를 사용할 때 주의사항
Intro 회사에서 새로운 프로젝트에 투입되었고 kotlin, spring webflux, r2dbc를 사용하기로 하였습니다. 회사의 기존 프로젝트는 mongoDB를 사용하느라 spring data mongo를 사용했었는데 새로운 프로젝트에서는 RDB를 쓰게 되면서 R2DBC를 사용하게 되었습니다. 그러다가 단순 조회를 하는 API를 하나 만들었는데 과거에 spring data jpa를 공부했을 때 조회 시 자주 사용했던 @Transactional(readOnly = true) 도 R2DBC에서 사용가능한 것을 알았고 이 글은 R2DBC 사용하고 단순 조회 기능을 개발할 때 @Transactional 기능을 사용하면 안좋다는 것을 알게되서 작성하는 글입니다. 시작은 코파일럿 단순 조회 기

자동메소드 saveAll을 Repository에 선언했을 때 발생하는 에러
문제 이렇게 requestBody로 보냈는데 contents가 하나일 때는 로직이 정상적으로 작동하는데 (save 성공) 여러 개일 때는 아래와 같은 에러 메시지가 출력됨 "message": "More than one onNext value for awaitSingleOrDefault" 원인 및 해결 saveAll이란 자동 메소드를 쓰는데, 실수로 repository에 saveAll 함수를 선언해놨더니 하나만 저장되는 save 함수가 된 모양이다 근데 신기한 건… save는 원래 list 로 들어가면 안될텐데 에러가 전혀 안남…; 여튼 saveAll 같은 자동 메소드는 Repository에서 선언하지 않고 domainservice단에서 saveAll 바로 써주는 식으로 해야한다. 이렇게 하니까 에러 없이 정상 작동한다.

네? Webflux에선 Pagination을 못쓴다고요? 그럼 만들지 뭐...
⚠️ 해당 게시글은 필자가 마이다스아이티 인턴십을 진행하며 겪은 문제들을 해결하는 내용을 담았으며, 보안 상 문제되지 않는 선의 내용까지만 공개한다는 조건으로 멘토님께 작성/게시 허가를 받았습니다. 🤔 문제 상황 개발 도중 발생한 문제 마이다스아이티 인턴십 과제를 수행하던 도중, 페이지네이션을 구현해야 하는 상황이 생겼다. Spring MVC를 사용하던 평소라면 JPA에서 제공하는 JpaRepository를 이용해 손쉽게 구현할 수 있는 기능이었지만, 이번에는 Webflux와 R2DBC를 이용하는 프로젝트였기에 페이지네이션에 대한 자료를 검색해 보았다. 그런데... 공식 문서와 각종 블로그, Stack Overflow 등지에서 찾아본 결과, R2DBC에서는 PagingAndSortRepository와 같은 레포지터리 인터페이스가 존재하지 않으며 Mono>와 같은 반환값도 지원하지 않는다고 한다. 각종 개발 커뮤니티에서는 (`find

Spring WebFlux 프로젝트 CloneFlix with chatGPT(4) - jOOQ
너무 힘든 R2DBC 환경 전 글에서는 Spring webflux R2DBC 환경에서 querydsl을 사용하였다. 단순히 데이터베이스로부터 select, insert 두가지만 해보았고 충분히 사용할만하다고 생각했다. 포스팅을 마친 후 연관관계가 있는 두 테이블을 만들고 MVC 때처럼 간편하게 매핑하기 위한 방법을 알아보았다. 하지만 R2DBC Querydsl환경에서는 연관관계를 포함하고 있는 결과를 조회하고 나서 자동으로 매핑되는 방법은 없다고 판단하였다. ChatGPT를 계속 괴롭히며 구글링을 해보았지만 제자리 걸음이였다.  시 isNew() 판단 못하는 문제
개발환경 OS: Windows 11 IDE: IntellJ IDEA 2022.2.4 (Ultimate Edition) Java: 1.8 Framework: Springframework.boot version: 2.4.3 Dependencies: \* 아래 코드는 예시 코드로 변경한 것임 상황 제목 그대로 1개 이상의 데이터 리스트를 업데이트 하기 위해 saveAll() 메소드를 사용했는데 새로운 객체인지 업데이트 대상 객체인지 판단하지 못함. 계속 insert만 하거나 update만 하려고 해서 unique 관련 에러 등이 발생함. 스키마 변경 불가 시도한 방법들 Entity에 implements Persistable 후 직접 isNew()를 재정의 @Value 어노테이션 사용 @Generated 어노테이션 사용 삽입/업데이트 리스트에서 하나씩 값 조회 후 isNew() 설정 테이블 전체 조회
[ERR] r2dbc connector…
개발환경 OS: Windows 11 IDE: IntellJ IDEA 2022.2.4 (Ultimate Edition) Java: 1.8 DB: MariaDB(10.9.3-MariaDB-1:10.9.3+maria~ubu2204) Framework: Springframework.boot version: 2.4.3 Dependencies: 상황 connector 들이 다 온전치 못해서 예상치 못한 오류를 너무 뱉는다.. 바쁘니까 대충 찾아본 결과 mariadb 커넥터는 maven 형태만 지원하고 gradle은 테스트만 지원하는 거 같은데 이부분이 잘 이해가 되지 않는다… ((Official) r2dbc-mariadb - native driver implemented for MariaDB) 그래서 위의 드라이버로 검색해보다가 찾은 gradl
[ERR] r2dbcRepository.save()가 안돼...
개발환경 OS: Windows 11 IDE: IntellJ IDEA 2022.2.4 (Ultimate Edition) Java: 1.8 Framework: Springframework.boot version: 2.4.3 Dependencies: 상황 R2dbcRepository 상속 후 save(Entity) 실행했으나 오류는 안 나지만 insert나 update 반영이 안되어있음. 기존 코드 FruitRepository.java @service FruitClient.java 해결 이렇게 실행하면 오류는 안 나는데 insert나 update 반영이 안되어있음. → subscribe()를 붙이면 된다. 참고 [Save in ReactiveCrudRepository not inserting or updating records](https://stackoverflow.com/questions/60
WebFlux 기반에선 jpa는 권장하지 않는대..
개발환경 OS: Windows 11 IDE: IntellJ IDEA 2022.2.4 (Ultimate Edition) Java: 1.8 Framework: Springframework.boot version: 2.4.3 WebFlux라는 거 자체도 힘들었는데 왜... 쉬운게 하나도 없는거니 > JPA는 기본적으로 비동기를 제공하지 않는다. Webflux 모듈은 기본적으로 비동기 non-blocking 방식을 지원하는데 JPA를 사용하면 Database 부분에서 block되고, 그동안 thread가 기다리게 된다. 참고 - R2DBC를 사용해보자 (1) - 왜 사용할까? 그래서 울며 겨자먹기로 R2D2를 사용함. 고생 깨나 함. 시행착오를 겪는 과정이기 때문에 틀린 내용이 있을 수 있음. build.gradle application.yml FruitEnt

Spring-webflux muliti database @Trasactional 설정하기
Spring-webflux에서 MongoDB, R2DBC(MySQL) 2가지 DB를 사용하고 있고 JPA처럼 @Transactional을 사용하여 트랜잭션을 처리하고 싶었다. 구글링을 통해 여러 자료를 참고하여 @Transactional을 MongoDB, R2DBC 각각 사용할 수 있도록 설정했다. MongoDB transaction config R2DBC transaction config 그리고 transaction을 테스트 해보았다. MongoDB transaction test R2DBC transaction test 그런데 아래와 같은 오류가 발생하였다. MongoDB, R2DBC에 각각 설정한 transaction bean type이 동일하여 @Trasactional에서 어떤 bean을 사용할지 몰라서 발생하는 오류였다. 그래서 bean type이 충돌나지 않도록 MongoDB transaction conf
프로젝트 기본세팅
스펙 JDK11, Gradle, Kotlin 1.6.21, Springboot2.7.6, Mysql 5.7, R2DBC(jasync-sql) 코드 작성 1. Gradle Depencencies 세팅 r2dbc 구현체로 jasync-sql 을 사용한 이유는 dev.miku는 2020년 이후로 버전업이 중단된 반면에 jasync-sql 은 지금도 계속 버전업 중이라 jasync-sql을 선택했다. 2. application.yaml 세팅 data.r2dbc.repositories.enabled: true 이 옵션은 application.yaml 대신에 Applcation 클래스 파일에 @EnableR2dbcRepositories 를 선언하는 방식으로도 설정 가능하다. 3. 비지니스 코드작성 Entity 코드 Repository 코드 다른 예제들을 찾아봤을때 ReactiveCrudRepository 를 상속받는 예제도 많이 보였는데

[R2DBC 알아보기] 3. Webflux와 R2DBC
R2DBC를 사용한다고 하면, 자주 같이 쓰이는 기술이 Webflux다. Webflux는 무엇이며, 어떤 이유로 Webflux + R2DBC 조합을 같이 쓰는 것일까? Spring Webflux란? (feat. Spring MVC) 우선 비교적 자주 쓰이는 SpringMVC와 비교하며 Spring Webflux를 이해해보자. Spring MVC와 Spring Webflux의 차이점 blocking / non-blocking Spring MVC 공식문서에 따르면, Spring Webflux 대부분의 구조 및 설정은 Spring MVC와 동일하다고 명시되어 있다. 그러나 동시성 모델과 블로킹/쓰레드 기본 전략이 다르다. MVC에서는 애플리케이션이 스레드를 차단(blocking)할 수 있다는 가정 하에 큰 스레드풀을 가지고 있고, **WebFlux에서는 스레드가 차단되지 않아(non-blocking) 적은 스레드풀을 사용하

[R2DBC 알아보기] 2. Reactive Programming이란?
‘리액티브 프로그래밍’은 무엇인가? 리액티브 프로그래밍에서 중요한 키워드 4가지, non-blocking, streaming, push, back pressure를 중심으로 알아가보자. (인용글 파티) streaming 우선 스트리밍 처리에 대해 알아보자. 이건 line 공식 블로그에 너무 좋은 설명이 있어서 일부를 가져와 공유해본다. > 아래 그림은 전통적인 데이터 처리 방식과 스트리밍 처리 방식을 비교한 그림이다. > > > https://engineering.linecorp.com/wp-content/uploads/2020/02/reactivestreams1-1.png > > 왼쪽의 전통적인 데이터 처리 방식에서는, 데이터 처리 요청이 오면 페이

[R2DBC 알아보기] 1. R2DBC란 무엇인가?
1. R2DBC R2DBC 정의 R2DBC (Reactive Relational Database Connectivity)는 이름 그대로 관계형 DB에서 reactive programming을 가능하게 해주는 데이터베이스 접근 API다. 관계형 DB 개념을 모르겠다면 아래의 링크 참고 (추후 추가 예정) Reactive programming을 잘 모르겠다면 이 시리즈의 2번째 글(아래 링크) 참고 https://velog.io/@effirin/R2DBC-2.-Reactive-Programming%EC%9D%B4%EB%9E%80-zh843mp2 R2DBC의 등장 배경 그리고 장점 R2DBC는 적은 스레드로 동시성을 처리하고 더 적은 하드웨어 리소스로 확장할 수 있는 논블로킹(non-blocking) 어플리케이션 스택이 필요해지면서 등장했다. 기존에 많이 쓰이던 관계형
Spring Webflux & QueryDSL
Spring Webflux에 dynamic query를 사용하기 위해서 QueryDSL을 붙히려고 했다. Reactive에 맞는 것을 붙히기 위해 r2dbc & QueryDSL을 채택해서, https://github.com/infobip/infobip-spring-data-querydsl/issues 를 참조해서 진행했다. 환경 : Spring Webflux, PostgreSQL (with r2dbc), gradle gradle 파일 내용 > implementation 'com.fasterxml.jackson.core:jackson-databind:2.13.3' implementation group: 'org.json', name: 'json', version: '20200518' implementation group: 'com.googlecode.json-simple', name: 'json-simple', ver
[MariaDB] r2dbc batch insert, webflux blocking call 처리
현재 webflux 와 r2dbc 를 활용하여 다중 api를 개발하던 중, r2dbc 에서 batch insert 를 어떻게 사용하는지 찾아보게되었고, 이를 공유해 보고자 한다. 우선 R2dbcCrudRepository 를 사용하고 있었기 때문에, 단순히 batch insert를 위해서는 제공하는 saveAll 메서드를 사용해도된다. 궁금하니 다른 방법도 알아보자. MariaDB의 공식문서에 r2dbc batch insert 의 예시가 잘 나와있다. 공식 문서를 참고해서 batch insert 로직을 작성했다. 위와 같이 VALUES 에 문자열 변수를 넣을 땐 '' 작은 따옴표로 감싸는 것을 잊지말자. 그렇지 않으면 unknown column 컬럼명 in field list 라는 에러를 만날 수 있다... 이렇게 작성 후 실행을 해보면 아마 에러가 날 것이다. 왜냐하면 block() 메서드 때문이다. 논블로킹 처리 중 block()

R2DBC & QueryDsl 같이 쓰기 - Webflux(0)
Webflux + R2DBC 스택에 대해 공부하고 있습니다. 본 게시글은 이해도가 성숙되기 전, 삽질(?) 로그를 담고 있어 그다지 유익하지 않을 수도 있습니다. 😂 https://github.com/infobip/infobip-spring-data-querydsl 라이브러리를 주제로 다루고 있습니다. 최근에 리액티브 프로그래밍도 공부 할 겸, MVC & Jpa로 개발해두었던 사이드 프로젝트 서버 환경을 Webflux & R2DBC로 마이그레이션 할 일이 생겼습니다. 관련 Git Repository (Kotlin + Spring 으로 할 수 있는 건 다 하고 있는 어마어마한 프로젝트.. ㅋㅋㅋ 조만간 블로그에 정리해두어야겠다.) 제대로 써본 적은 없지만, 어깨 너머로 경험해본 R2DBC 생태계는 JPA에 비해 너무나도 미성숙해 보였습니다. _(나름 메이저
R2DBC란
R2DBC 다음은 Spring Data R2DBC 레퍼런스에 나와있는 R2DBC에 대한 설명이다. >R2DBC is the acronym for Reactive Relational Database Connectivity. R2DBC is an API specification initiative that declares a reactive API to be implemented by driver vendors to access their relational databases. R2DBC는 비동기 프로그래밍과 함께 사용된다. 반면, JDBC는 동기적으로 동작하므로 별도의 조작 없이는 비동기 프로그래밍에서 사용하기 적절하지 않다. 동기/비동기 프로그래밍은 많이 들어봤지만 데이터베이스 계층에서의 구현도 동기/비동기로 나뉠 수 있다는 사실을, 그래서 목적에 맞는 데이터베이스 드라이버 구현체를 사용해야 한다는 사실을 오늘 처음 알았다. 비동기 프로그래밍을 공부하기 위해
개발일기 - 2022-05-04
08:00 책상에 앉았다. PostgreSQL를 잘 써보자 생각하고 진행하고 있으나, DB계의 양대 산맥인 익숙했던 MySQL 과는 꽤나 다르다는 것을 실감하고 있다. 여기에 R2DBC도 한몫 단단히 하고 있다. 오늘은 jsonb 타입에 대해서 알아봤다. 테이블 설계시 메타데이터등을 jsonb 타입으로 저장하고 관리하는데, 때로는 인덱스가 필요한 경우가 있어 인덱스가 있는 필드와 없는 필드로 구분하여 사용중이다. 갑자기 과거 카산드라의 무지막지한(?) 인덱스 때문에 고생을 한 추억이 새록 떠올랐다. 암튼, jsonb 에도 인덱스를 생성할 수 있는데 비교적 여기가 잘 설명되어 있다. [Using JSONB in PostgreSQL: How to Effectively Store & Index JSON Data in PostgreSQL](https://scalegrid.io/blog/using-jsonb-in-postgresql-how-to-effe

[Spring Webflux + R2DBC] 게시판 CRUD 예제 (1)
본 글은 Spring MVC 개발 경험을 전제로 작성되었습니다. 들어가기 앞서 신규 개발 프로젝트에 Spring Webflux 도입을 검토하게 되어 간단하게 구현해본 토이 프로젝트를 공유해보고자 한다. 아직 상용화하기에는 시기상조인, 비교적 최근에 개발된 프레임워크라서 그런지 따라해볼만한 예제의 부재를 느껴 처음으로 작성하게 된 포스트이다. 이론 및 개념적인 요소에 대한 포스팅은 이미 많기에 링크로 첨부하거나 생략할 것이며, Reactive 프로그램에 대해 가볍게 경험하고자 하는 목적으로 실제 동작하는 코드(돌면 장땡) 위주로 풀어나갈 예정이다. 개발 환경 IDE: IntelliJ Language: JAVA 11 Database: Postgres / R2DBC 프로젝트 구조 ![](https://images.velog.io/images/hans96/post/a02f547d-d28c-4a8f-a035-cb04f805a583/imag