ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • @Transactional 에 대한 고찰
    Spring 2023. 3. 26. 21:43

     스프링에서 트랜잭션 처리를 지원하는데 어노테이션 방식으로 @Transactional 을 선언하여 사용하는데,

    여기서 얘기하는 트랜잭션 개념은 다른 글에서도 워낙 많은 편이니 생략하도록 하겠다.

     

     

    @Transactional 이란?

     

    메서드나 클래스에 @Transactional 추가하게 되면

    자동적으로 트랜잭션을 시작하고, 정상 여부에 따라 Commit 또는 Rollback 하게 된다. 

     

    위에서 얘기한 @Transactional 추가 위치에 따른 처리 차이에 대한 내용이다.

    메서드에 추가한 경우: 해당 메서드만 트랜잭션 처리

    클래스에 추가한 경우: 모든 메서드의 트랜잭션 처리

     

    @Transactional 사용시 주의점

     

    다음 내용은 최범균님의 '프로그래밍 초식 : 초심자가 저지르기 쉬운 DB 코딩 실수 3가지' 에서 나온 내용이다.

     

    다음과 같은 코드가 있다.

     

    1번

        @Transactional
        public void registerMembers(List<Req> reqs) {
            reqs.forEach(req -> {
               try {
                   registerService.register(req);
                   logDao.insert(createSuccessLog(req, ex));
               } catch (Exception ex) {
                   logDao.insert(createFailLog(req, ex));
               }
            });
        }

     

    2번

        @Transactional
        public void register(Req req) {
            anyRepository.save(toData(req));
            if (check()) {
                throw new RuntimeException("!");
            }
        }

     

    위 '1번'처럼 @Transactional 안에 try catch를 하게 되면 

    의도한 대로 동작이 안되게 될 수 있다.

     

    loop를 돌면서 register 메서드를 호출하게 되는데 

    Exception이 발생하지 않으면 아무 문제가 없는 코드이지만

    register 에서 Exception이 발생하게 되면

    throw new RuntimeException("!"); 을 호출하면서 트랜잭션이 '롤백' 상태로 바뀌게 된다.

     

    이 상태가 되면 나머지 register와 insert는 롤백 상태에서 진행하게 되기 때문에 

    아무 의미가 없는 상태가 되어 버린다.

     

    그 후 forEach 문이 끝날때 커밋을 시도하게 되는데 지금 트랜잭션 상태가 롤백 상태이기 때문에

    커밋을 할 수가 없고, 커밋에 실패하게 된다.

     

    여기서 의도는 forEach 를 하면서 정상적인 수행과 실패가 난 사항들을 디비에 따로따로 기록하는 것이 의도였는데,

    @Transactional 이 있다보니 의도대로 동작하지 않는 것을 알 수 있다.

     

    이 케이스는 중첩된 @Transactional과 try-catch에 대한 내용인데, 

    메서드에 @Transactional 설정하고, 안에서 try-catch로 Exception을 처리하고 전파하지 않으면

    다음과 같은 내용이 확인 필요하다.

     

    1. 중첩된 @Transactional이 있는지

    2. 의도하지 않은 롤백 가능성이 없는지

    3. 의도한 롤백이 안될 가능성은 없는지 

     

    그래서 위 케이스에서는 의도한대로 트랜잭션이 동작하는지 테스트가 필요하다.

     

    @Transactional 분리 사용

    TBD

     

    출처: https://morioh.com/p/a97ace580213

    출처: https://goddaehee.tistory.com/167

    출처: https://www.youtube.com/watch?v=n85UzIReFjY&t=313s&ab_channel=%EC%B5%9C%EB%B2%94%EA%B7%A0 

     

    'Spring' 카테고리의 다른 글

    JPA Hibernate Proxy  (1) 2022.09.13
    Spring API 공통 response 포맷 개발하기  (1) 2022.07.10
Designed by Tistory.