[JPA] 트랜잭션 save() 반영 안 되는 문제

2025. 5. 12. 17:23·트러블슈팅

문제 현상

간단한 POST API 호출 이후 (회원가입) entity -> dto 변환 시 id가 반영되지 않는 문제가 발생하였다.

    @PostMapping()
    fun createMember(@Valid @RequestBody dto: SignupRequest): ApiResponse<MemberResponse> {
        val createdMember = memberService.createMember(dto)
        return ApiResponse.success(MemberResponse.from(createdMember))
    }
    @Transactional
    fun createMember(dto: SignupRequest): Member {
        val member = Member(
            nickname = dto.nickname,
            name = dto.name,
            password = dto.password?.let { passwordEncoder.encode(it) },
            email = dto.email,
            profileImage = dto.profileImage
        )
        val savedMember = memberRepository.save(member)
        return savedMember
    }

id가 반영되지 않았다는 것은 DB에도 저장이 되지 않았다는 의미였고 DDL상에서 auto_increment 옵션이 없다던가 하는 문제도 없었다.

 

실례지만... 어데 트씹니꺼?

따라서 트랜잭션이 정상적으로 활성화 되어있는지? 살펴보기 위해 아래와 같이 로그를 추가해두었다.

    @Transactional
    fun createMember(dto: SignupRequest): Member {
        println(AopUtils.isAopProxy(memberRepository))
        println("트랜잭션 활성화 여부: ${TransactionSynchronizationManager.isActualTransactionActive()}")
        val member = Member(
            nickname = dto.nickname,
            name = dto.name,
            password = dto.password?.let { passwordEncoder.encode(it) },
            email = dto.email,
            profileImage = dto.profileImage
        )
        val savedMember = memberRepository.save(member)
        return savedMember
    }

프록시, 트랜잭션 모두 활성화되어 있다는 로그를 확인하였으나 여전히 save가 작동하지 않았다.

따라서 saveAndFlush 메서드로 수정해서 테스트를 진행해보았다.

    @Transactional
    fun createMember(dto: SignupRequest): Member {
        println(AopUtils.isAopProxy(memberRepository))
        println("트랜잭션 활성화 여부: ${TransactionSynchronizationManager.isActualTransactionActive()}")
        val member = Member(
            nickname = dto.nickname,
            name = dto.name,
            password = dto.password?.let { passwordEncoder.encode(it) },
            email = dto.email,
            profileImage = dto.profileImage
        )
        val savedMember = memberRepository.save(member)
        return savedMember
    }
no transaction is in progress

saveAndFlush로 고쳤으나 이제 트랜잭션 상태가 이상하다는 것을 꺠닫고 열심히 구글링 해보았다.

한 github issue에서

spring:
  jpa:
    open-in-view: false
    hibernate:
      ddl-auto: update
    properties:
      hibernate:
        allow_update_outside_transaction: true

위와 같이 allow_update_outside_transaction를 true로 설정하면 된다는 것을 보고 true로 설정하고 다시 테스트 해보았다.

true로 설정하고 나니 정상적으로 insert되고 API도 정상 응답된 것을 확인하였다.

다만, 이는 임시적인 해결책이고 save() 호출 및 해당 옵션을 활성화 하지 않아도 작동하게끔 수정해야한다.

따라서 현재 문제 상황은 다음과 같다.

메서드 allow_update_outside_transaction: true allow_update_outside_transaction: false
save() X X
saveAndFlush() 정상 작동 (DB에 insert됨)
즉시 flush 수행하여 DB 반영
X

따라서 saveAndFlush 상태에서 allow_update_outside_transaction: true로 하였을 시에만 정상 작동하는 것을 보고 어떤 설정에서 트랜잭션이 가로채기 당하고 있다는 느낌이 들었다.

 

 

애덤 스미스 연전연승

 

따라서 transactionManager를 검색해보니

@Configuration
@EnableBatchProcessing
class BatchConfig(private val dataSource: DataSource) {

    @Bean
    @Primary
    fun batchTaskExecutor(): TaskExecutor {
        val executor = SimpleAsyncTaskExecutor("batch-executor-")
        executor.concurrencyLimit = 10
        return executor
    }

    @Bean
    fun transactionManager(): PlatformTransactionManager {
         return DataSourceTransactionManager(dataSource)
    }

그냥 같은 폴더에 Spring batch Config를 설정해두었었는데 transactionManager를 여기서 정의하고 있어서 그랬다.. ;;
메서드마다 서로 다른 트랜잭션 매니저를 쓰기때문에 트랜잭션이 제대로 작동하지 않았던 문제였다.

'트러블슈팅' 카테고리의 다른 글
  • A param property was accessed directly with `params.id`. `params` is now a Promise and should be unwrapped with `React.use()` before accessing properties of the underlying params object. In this version of Next.js direct access to param properties is stil
  • NoSuchFieldError: Class org.opensearch.client.Requests does not have member field 'org.opensearch.core.xcontent.MediaType INDEX_CONTENT_TYPE'
  • Using slow pure-python SequenceMatcher. Install python-Levenshtein to remove this warning
  • [JAVA] Swagger에서 파라미터 숨기기(커스텀 어노테이션 @CurrentUser)
minseok__
minseok__
  • minseok__
    minseok_study
    minseok__
  • 전체
    오늘
    어제
    • 분류 전체보기 (89)
      • JAVA (1)
      • Kotlin (0)
      • CS (1)
      • SQL (7)
      • Python (2)
      • Docker (13)
      • Typescript (0)
      • Javascript (1)
      • AWS (6)
      • NestJS (1)
      • ElasticSearch (1)
      • 트러블슈팅 (10)
      • DB (6)
      • 알고리즘 (5)
      • Redis (1)
      • Postgresql (1)
      • AI (0)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    SQL
    외래키 참조
    docker
    error: relation "batch_job_instance" does not exist
    response data
    userauth_pubkey: key type ssh-rsa not in pubkeyacceptedalgorithms
    쿠버네티스
    node.js 20
    EC2
    window
    openssh 8.8
    윈도우
    반환 데이터
    mysql 아키텍처
    빅쿼리
    bigquery
    amazon linux 2023
    k8s
    createMany
    useswrinfinite
  • 최근 댓글

  • hELLO· Designed By정상우.v4.10.3
minseok__
[JPA] 트랜잭션 save() 반영 안 되는 문제
상단으로

티스토리툴바