• 카테고리

    질문 & 답변
  • 세부 분야

    백엔드

  • 해결 여부

    미해결

트랜잭션 관련 질문드립니다.

23.01.26 08:28 작성 조회수 204

0

- 학습 관련 질문을 남겨주세요. 상세히 작성하면 더 좋아요!
- 먼저 유사한 질문이 있었는지 검색해보세요.
- 서로 예의를 지키며 존중하는 문화를 만들어가요.
- 잠깐! 인프런 서비스 운영 관련 문의는 1:1 문의하기를 이용해주세요.

 

안녕하세요, 이전에 트랜잭션 범위 질문 관련하여 추가 질문드리려고 합니다 :)

 

단일 tasklet에서 여러 테이블을 update할 때 하나를 업데이트하고 뒤에서 오류가 나면 롤백이 안되는데 보통 실무에서 어떻게 사용하는지 궁금합니다.

예를 들면 아래와 같이 하나의 tasklet 내에서 2개의 업데이트 작업이 필요하고, 이 두 테이블 업데이트가 하나의 트랜잭션에 묶여야 할 때 어떤식으로 작업을 주로 하는지 궁금합니다.

new tasklet() {

    // 테이블1 업데이트 로직
    table1Service.update();

    // 오류 발생
    throw new RuntimeException("오류 발생");

    // 테이블2 업데이트 로직
    table2Service.update();

}

(chunk 단위로 업데이트할 정도로 업데이트할 양이 많지 않아 따로 itemReader/itemProcess/itemWriter 구현을 하지 않은 단일 tasklet 예시입니다)

그리고, 테이블 업데이트 로직이 다른 서비스 로직을 호출하여서 업데이트하는것이라면 해당 서비스 로직의 transaction에 springbatch가 만들어준 transaction이 전파되지 않는 이유가 궁금합니다.

step 실행을 함으로써 springbatch가 생성해준 트랜잭션 내부에서 서비스를 호출하여서 해당 트랜잭션이 전파되어서 서비스의 트랜잭션이 자식 트랜잭션이 될 것이라 생각하였는데, 실제로 테스트했을 때 각각 따로 트랜잭션 처리가 되어 롤백이 제대로 이루어지지 않는 것으로 보여서 문의드립니다.

 

답변 1

답변을 작성해보세요.

0

일단 table1Service 와 table2Service 에 적용된 트랜잭션이 스프링 배치 트랜잭션과 동일한 것인지 부터 확인해 봐야 합니다.

스프링에서 @Transactional 을 선언하게 되면 해당 클래스 즉 서비스는 프록시로 생성이 되고 서비스가 호출이 되면 트랜잭션 매니저가 새로운 트랜잭션을 생성해서 처리하게 되는데 이 때 스프링 배치의 트랜잭션을 해당 서비스가 그대로 물려 받는지를 확인하는게 중요한 것 같습니다.

기본적으로 스프링 배치는 외부 트랜잭션을 차단하는 정책을 펼치고 있습니다.

즉 서비스에 별도의 @Transactional 을 선언하지 않고 실행해 보시고 가능하시면 소스 공유 해 주시면 테스트 해 보도록 하겠습니다.