강의

멘토링

로드맵

Cộng đồng Hỏi & Đáp của Inflearn

Hình ảnh hồ sơ của kimseunghyunkr
kimseunghyunkr

câu hỏi đã được viết

Spring DB Phần 2 - Kỹ thuật sử dụng truy cập dữ liệu

spring webflux 와 spring data jpa Transaction 사용 시 문제

Viết

·

1.3K

0

토이프로젝트를 하다 어쩌다 보니 spring webflux를 사용하게 되고 spring data jpa 는 reactive 환경에서 사용하지 못한다는 것을 모른 채 개발하다가...

@SpringBootTest 에서 @Transactional 을 쓴 테스트에서 롤백이 되지 않는 현상을 발견했습니다..

 

 

TRACE 로 설정해 두고 실행시켜본 결과...```2024-01-11T00:54:00.058+09:00  INFO 18764 --- [    Test worker] c.s.o.s.StockMarketDataServiceTest       : Started StockMarketDataServiceTest in 10.371 seconds (process running for 11.483)
2024-01-11T00:54:00.124+09:00 DEBUG 18764 --- [    Test worker] o.s.orm.jpa.JpaTransactionManager        : Creating new transaction with name [com.stock.oppenheimer.service.StockMarketDataServiceTest.testAddByStockName]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT
2024-01-11T00:54:00.125+09:00 DEBUG 18764 --- [    Test worker] o.s.orm.jpa.JpaTransactionManager        : Opened new EntityManager [SessionImpl(2129901484<open>)] for JPA transaction
2024-01-11T00:54:00.132+09:00 DEBUG 18764 --- [    Test worker] o.s.orm.jpa.JpaTransactionManager        : Exposing JPA transaction as JDBC [org.springframework.orm.jpa.vendor.HibernateJpaDialect$HibernateConnectionHandle@7b5f886d]
2024-01-11T00:54:00.606+09:00 DEBUG 18764 --- [    Test worker] o.s.orm.jpa.JpaTransactionManager        : Found thread-bound EntityManager [SessionImpl(2129901484<open>)] for JPA transaction
2024-01-11T00:54:00.606+09:00 DEBUG 18764 --- [    Test worker] o.s.orm.jpa.JpaTransactionManager        : Participating in existing transaction
2024-01-11T00:54:00.606+09:00 TRACE 18764 --- [    Test worker] o.s.t.i.TransactionInterceptor           : Getting transaction for [com.stock.oppenheimer.service.StockMarketFacadeService.addStockMarketData]
2024-01-11T00:54:00.607+09:00 DEBUG 18764 --- [    Test worker] o.s.orm.jpa.JpaTransactionManager        : Found thread-bound EntityManager [SessionImpl(2129901484<open>)] for JPA transaction
2024-01-11T00:54:00.607+09:00 DEBUG 18764 --- [    Test worker] o.s.orm.jpa.JpaTransactionManager        : Participating in existing transaction
2024-01-11T00:54:00.607+09:00 TRACE 18764 --- [    Test worker] o.s.t.i.TransactionInterceptor           : Getting transaction for [com.stock.oppenheimer.service.StockDataService.addStockData]
2024-01-11T00:54:00.628+09:00 TRACE 18764 --- [    Test worker] o.s.t.i.TransactionInterceptor           : Completing transaction for [com.stock.oppenheimer.service.StockDataService.addStockData]
2024-01-11T00:54:00.629+09:00 TRACE 18764 --- [    Test worker] o.s.t.i.TransactionInterceptor           : Completing transaction for [com.stock.oppenheimer.service.StockMarketFacadeService.addStockMarketData]
2024-01-11T00:54:02.705+09:00 DEBUG 18764 --- [ctor-http-nio-2] o.s.orm.jpa.JpaTransactionManager        : Creating new transaction with name [org.springframework.data.jpa.repository.support.SimpleJpaRepository.save]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT
2024-01-11T00:54:02.706+09:00 DEBUG 18764 --- [ctor-http-nio-2] o.s.orm.jpa.JpaTransactionManager        : Opened new EntityManager [SessionImpl(576234319<open>)] for JPA transaction
2024-01-11T00:54:02.706+09:00 DEBUG 18764 --- [ctor-http-nio-2] o.s.orm.jpa.JpaTransactionManager        : Exposing JPA transaction as JDBC [org.springframework.orm.jpa.vendor.HibernateJpaDialect$HibernateConnectionHandle@183cb66b]
2024-01-11T00:54:02.706+09:00 TRACE 18764 --- [ctor-http-nio-2] o.s.t.i.TransactionInterceptor           : Getting transaction for [org.springframework.data.jpa.repository.support.SimpleJpaRepository.save]
2024-01-11T00:54:02.749+09:00 TRACE 18764 --- [ctor-http-nio-2] o.s.t.i.TransactionInterceptor           : Completing transaction for [org.springframework.data.jpa.repository.support.SimpleJpaRepository.save]
2024-01-11T00:54:02.749+09:00 DEBUG 18764 --- [ctor-http-nio-2] o.s.orm.jpa.JpaTransactionManager        : Initiating transaction commit
2024-01-11T00:54:02.749+09:00 DEBUG 18764 --- [ctor-http-nio-2] o.s.orm.jpa.JpaTransactionManager        : Committing JPA transaction on EntityManager [SessionImpl(576234319<open>)]
2024-01-11T00:54:02.758+09:00 DEBUG 18764 --- [ctor-http-nio-2] o.s.orm.jpa.JpaTransactionManager        : Closing JPA EntityManager [SessionImpl(576234319<open>)] after transaction
2024-01-11T00:54:02.759+09:00 DEBUG 18764 --- [ctor-http-nio-2] o.s.orm.jpa.JpaTransactionManager        : Creating new transaction with name [com.stock.oppenheimer.service.MarketDataService.fetchMarketData]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT
2024-01-11T00:54:02.759+09:00 DEBUG 18764 --- [ctor-http-nio-2] o.s.orm.jpa.JpaTransactionManager        : Opened new EntityManager [SessionImpl(222446599<open>)] for JPA transaction
2024-01-11T00:54:02.759+09:00 DEBUG 18764 --- [ctor-http-nio-2] o.s.orm.jpa.JpaTransactionManager        : Exposing JPA transaction as JDBC [org.springframework.orm.jpa.vendor.HibernateJpaDialect$HibernateConnectionHandle@7a4f5e33]
2024-01-11T00:54:02.759+09:00 TRACE 18764 --- [ctor-http-nio-2] o.s.t.i.TransactionInterceptor           : Getting transaction for [com.stock.oppenheimer.service.MarketDataService.fetchMarketData]
2024-01-11T00:54:02.760+09:00 TRACE 18764 --- [ctor-http-nio-2] o.s.t.i.TransactionInterceptor           : Completing transaction for [com.stock.oppenheimer.service.MarketDataService.fetchMarketData]
2024-01-11T00:54:02.761+09:00 DEBUG 18764 --- [ctor-http-nio-2] o.s.orm.jpa.JpaTransactionManager        : Initiating transaction commit
2024-01-11T00:54:02.761+09:00 DEBUG 18764 --- [ctor-http-nio-2] o.s.orm.jpa.JpaTransactionManager        : Committing JPA transaction on EntityManager [SessionImpl(222446599<open>)]
2024-01-11T00:54:02.761+09:00 DEBUG 18764 --- [ctor-http-nio-2] o.s.orm.jpa.JpaTransactionManager        : Closing JPA EntityManager [SessionImpl(222446599<open>)] after transaction
2024-01-11T00:54:03.536+09:00 DEBUG 18764 --- [ctor-http-nio-2] o.s.orm.jpa.JpaTransactionManager        : Creating new transaction with name [org.springframework.data.jpa.repository.support.SimpleJpaRepository.save]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT
2024-01-11T00:54:03.537+09:00 DEBUG 18764 --- [ctor-http-nio-2] o.s.orm.jpa.JpaTransactionManager        : Opened new EntityManager [SessionImpl(1744980953<open>)] for JPA transaction
2024-01-11T00:54:03.537+09:00 DEBUG 18764 --- [ctor-http-nio-2] o.s.orm.jpa.JpaTransactionManager        : Exposing JPA transaction as JDBC [org.springframework.orm.jpa.vendor.HibernateJpaDialect$HibernateConnectionHandle@364f6c3d]
2024-01-11T00:54:03.537+09:00 TRACE 18764 --- [ctor-http-nio-2] o.s.t.i.TransactionInterceptor           : Getting transaction for [org.springframework.data.jpa.repository.support.SimpleJpaRepository.save]
2024-01-11T00:54:03.546+09:00 TRACE 18764 --- [ctor-http-nio-2] o.s.t.i.TransactionInterceptor           : Completing transaction for [org.springframework.data.jpa.repository.support.SimpleJpaRepository.save]
2024-01-11T00:54:03.546+09:00 DEBUG 18764 --- [ctor-http-nio-2] o.s.orm.jpa.JpaTransactionManager        : Initiating transaction commit

```

이러한 상황을 경험하게 되었습니다.

2024-01-11T00:54:02.706+09:00 DEBUG 18764 --- [ctor-http-nio-2] o.s.orm.jpa.JpaTransactionManager        : Opened new EntityManager [SessionImpl(576234319<open>)] for JPA transaction
2024-01-11T00:54:02.759+09:00 DEBUG 18764 --- [ctor-http-nio-2] o.s.orm.jpa.JpaTransactionManager        : Opened new EntityManager [SessionImpl(222446599<open>)] for JPA transaction
2024-01-11T00:54:03.537+09:00 DEBUG 18764 --- [ctor-http-nio-2] o.s.orm.jpa.JpaTransactionManager        : Opened new EntityManager [SessionImpl(1744980953<open>)] for JPA transaction

기존에 쓰이던 엔티티매니저가 없어지고 계속 새로운 엔티티 매니저가 오픈이 되고 있었습니다.

 

2024-01-11T02:01:18.229+09:00 DEBUG 25524 --- [    Test worker] o.s.orm.jpa.JpaTransactionManager        : Rolling back JPA transaction on EntityManager [SessionImpl(1495319789<open>)]

하지만 마지막에 롤백 되는 엔티티메니저는 [Test worker thread] 에서 소환한 엔티티매니저 단 하나였습니다.

 

해당 부분을 소환하는 코드는 이렇습니다..

 

@Transactional
public Flux<MarketData> saveMarketData(MktDataDTO marketDataDTO, StockData savedStockData) {
    MarketData marketData = conversionService.convert(marketDataDTO, MarketData.class);
    marketData.setStockData(savedStockData);
    marketDataRepository.save(marketData);
    return Flux.just(marketData);
}

 

골이 당겨 오네요 ㅜㅜㅜ..

r2dbc 로 마이그레이션을 하지 않고 transaction 설정을 잘 이용해서 이 상황을 해결할 방법이 있을지 한번 여쭤봅니다.

코드 전문은

kimseunghyun-kr/oppenheimer at VolumeProfile (github.com)
여기 있습니다..

springmvcjpaquerydslspring-data-mybatisspring-jpaspringwebflux

Câu trả lời 2

0

spring webflux는 reactor 구현체로 동작하는 non-blocking 웹어플리케이션 프레임웍인데요. spring data jpa하고 호환이 잘 안되는 것으로 알고 있습니다.

 

특히 webflux 환경에서 ReactiveCrudRepository가 아닌 JpaRepository 사용하는 경우 데이터 처리하는 과정에서 의도치 않은 방식으로 처리 될 수 있어서 주의가 필요합니다.

 

spring webflux, jpa 관련 자료 찾아보시면 바로 아실 수 있으실 거라 생각합니다.

0

yh님의 프로필 이미지
yh
Người chia sẻ kiến thức

안녕하세요. 승현님

이 부분은 저도 잘 모르겠습니다.

혹시 아시는 분 있으면 도움 부탁드려요.

감사합니다.

kimseunghyunkr님의 프로필 이미지
kimseunghyunkr
Người đặt câu hỏi

추가적으로 spring data jpa 랑 spring data r2dbc 이용해서 같은 데이터소스에 다른 드라이버 연결을 할려고 하는데 이러면 아예 그냥 jdbc 커넥션이 없다고 나오네요

Hình ảnh hồ sơ của kimseunghyunkr
kimseunghyunkr

câu hỏi đã được viết

Đặt câu hỏi