ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • @Transactional(readOnly = true)는 필요한가?
    개발/Spring 2021. 8. 8. 00:03

    회사에서 작업하면서 단순히 데이터 목록을 findall을 통해 조회한 값을 리턴하는 메서드에 당연하단 생각으로 @Transactional(readOnly = true) 을 주었었다.

    그리고 리뷰를 하는도중 동료가 @Transactional(readOnly = true)의 역할이 무엇인지 물었었고

    나는 readOnly=true인 상태이면 영속성 컨텍스트에 관리를 받지않아, 스냅샷 저장. 변경감지 수행등을 하지 않아 성능적으로 나아 이 옵션을 달았다고 답변을 했다.

    그리고 이어지는 질문은 그럼 해당 옵션이 아예 없으면 되는데, 왜 필요한가였다.

    떠올린 생각과 한 얘기는

    1. readonly true일때는 master가 아닌 reader DB로 호출되는 장점이 있지만 현재는 개발단계로 하나의 db만 사용하고 있기 때문에 해당사항이 아니었다. 그래도 생각난 장점은 전달하였다.

    2. 속성을 정의할때 transaction도 설정하였는데 달지 않아도 혹시 default transaction이 수행되고 자원을 소모하나? 그래서 해당 옵션이 있으면 낭비를 하지 않는걸까? 이런 생각이 떠올랐지만 터무니 없다는 판단되었고 이 역시 전달하였다. 

    3. 해당 경우는 아니었지만 보통 서비스단위에 @Transactional 이 붙는 경우가 있는데 이런경우는 확실히 따로 @Transactional(readOnly = true) 두어야 한다는 걸 전달하였다.

    4. 추후 서비스가 복잡한 경우를 대비하여, 그리고 Transaction을 모든 db연결에서 사용된다면 위와같이 조회인 경우엔 필요할 것 같고, 이보다 작은 경우에서도 명시적으로 두는 것이 좋을 것 같다는 생각을 전달하였다.

    이렇게 나는 제대로 된 답변은 하지 못한채 떠오른 생각을 전달하고 같이 찾아보자는 것을 끝으로 대화를 마쳤다.

     

    왜 필요할까?

     

    1.DBMS 별 Transaction Read Only에 대한 동작 방식 

    MySQL

    해당 트랜잭션을 이용할 경우 SELECT 문에 대해서만 기능을 지원하며, Transaction ID 설정에 대한 오버헤드를 해결할 수 있다. Read Only 트랜잭션에 대해서는 ID가 부여되지 않는다. 

     

    추가적으로 세션 별로 임시 테이블을 변경하거나 Lock 쿼리를 실행할 수 있는데, 이는 다른 트랜잭션(Read Write 혹은 다른 Read Only) 들이 가시 할 수 없는 범위이기 때문이다.

     

    Oracle과 마찬가지로 별도의 스냅샷을 통해 데이터를 조회하기 때문에, 데이터 일관성을 보장할 수 있다.

    → 트랜잭션 ID 설정에 대한 오버헤드를 해결하고, 스냅샷을 통해 데이터 일관성을 보장한다.

     

     

    사용한 mysql 내용만 작성하며 아래 블로그를 통해 자세히 알아보는게 좋을 것 같다.

     

    출처: https://lob-dev.tistory.com/entry/DBMS-별-Transaction-Read-Only에-대한-동작-방식-1 [Lob!]

     

    2. 사용 이유는?

     - 성능적인 이점

    해당 옵션인 경우 스프링 프레임워크가 하이버네이트 세션 플러시 모드를 MANUAL로 설정하기 때문에 강제로 플러시를 호출하지 않은 한 플러시가 일어나지 않아, CUD 작업이 동작하지 않고, 앞에 언급한대로 스냅샷 저장. 변경감지등의 작업을 수행하지 않아 성능이 향상된다.

    또한, DB가 master와 slave로 나누어져 있다면 ReadOnly가 있는 경우 읽기전용으로 slave를 호출하게 된다. 즉, 상황에 따라 DB 서버의 부하를 줄일 수 있다.

     - 해당 어노테이션이 있다면 우리는 해당 메서드는 READ에 대한 동작만 수행할 것이라고 예상하고 그리고 이루어진다. 여기서 난 객체지향으로 작업할때 가능한 경우 final을 두어 객체의 신뢰성을 보장하는것이 떠올랐다. 그리고 난 이 점이 중요하다고 느껴졌기에 해당 옵션에서 아무런 성능적 이점을 갖지 못한 경우라도 명시적으로 두어 계속 사용할 것 같다.

     

     

    지금은 조금 생각이 바꼈다.

    다음 글도 함께 읽으면 도움이 될 듯 하다

    https://cupeanimus.tistory.com/102?category=868009

    댓글

Designed by Tistory.