본문 바로가기
Spring

스프링 트랜잭션 @Transactional(readOnly=true)

by devLog by Ronnie's 2022. 12. 9.

@Transactional 옵션에는 여러가지 옵션 설정이 있지만 오늘은 그 중에서 readOnly 옵션에 대해서 정리하려고 한다.

옵션에서도 알 수 있듯이 읽기 전용이라는 것을 알 수 있다. 그렇다면 이런 의문점이 들 수 있다. 어짜피 조회만 하는 곳에 @Transactional 어노테이션을 붙일 필요가 있을까? 라는 의문점이다. 

 

결론적으로는 안붙인다고 문제가 될 것은 없지만 붙이게 된다면 여러가지 이점을 주기 때문에 붙이는 것이 좋다.

 

그럼 @Transactional(readOnly=true) 설정에 대해서 알아보자.

 

스프링 트랜잭션 @Transactional(readOnly=true)

 

스프링 트랜잭션 @Transactional(readOnly=true)

 

Transaction?


먼저 트랜잭션이란 데이터베이스의 상태를 변경하고자 할 때 한 번에 수행되어야 하는 연산들을 의미한다. 어떤 한 서비스 로직 안에 서로 다른 엔티티의 값을 변경한다고 예를 들면 A 엔티티 속성이 바뀌고 B 엔티티 속성이 바뀌기 전에 에러가 나게 되면 A 엔티티 속성을 다시 전으로 돌려줘야 한다. (트랜잭션의 4가지 성질인 ACID의 근거함)

 

그렇기 때문에 자연스럽게 데이터가 바뀌는 곳에는 @Transactional 어노테이션을 붙여 트랜잭션 처리를 하는 것이다.

 

그럼 이제 @Transactional(readOnly=true) 대해서 알아보자

 

@Transactional(readOnly=true)


먼저 @Transactional 어노테이션에 들어가서 확인해보면 readOnly default 값은 false이다. 그렇기 때문에 @Transactional 선언하면 readOnly 처리가 되지 않는다.

그래서 @Transactional(readOnly=true) 쓰기 위해서는 정의를 해줘야한다

 

 

@Transactional(readOnly=true) 쓰는 이유는 다음과 같다.

 

  1. 조회한 데이터를 반환하게 된다 해도 의도지 않게 데이터가 변경되는 일을 방지해준다.
  2. 코드의 가독성을 높혀준다. -> @Transactional(readOnly=true) 붙어있는 것을 발견한다면 코드를 접하는 사람들이 해당 메서드의 역할을 직관적으로 있다.
  3. CUD 작업이 동작하지 않고 스냅샷 저장을 하지 않고 변경 감지의 작업을 수행하지 않는다.
    1. JPA에서는 변경 감지를 통해 트랜잭션이 끝나느 시점에 변화가 있는 모든 엔티티 객체를 디비에 반영을 해주는데 이것을 변경 감지라 부르며, 이러한 행위를 가능하게 해주는 것이 스냅샷을 만들어 저장해놓기 때문이다. (해당 엔티티의 처음 상태를 스냅샷을 저장해놓고 트랜잭션이 끝나느 시점에 스냅샷과 비교 다른 점이 있다면 update)
    2. 이러한 행위들이 비용이기 때문에 readOnly=true 하게 된다면 해당 사항을 진행하기 않기 때문에 성능이 향상 된다.
  4. 데이터베이스의 구조가 master와 slave로 구성되어 있을때 readOnly=true인 경우는 읽기 전용으로 slave를 호출하게 되어 상황에 따라 DB 서버의 부하를 줄일 수 있다.
  5. readOnly=true 인 경우에는 Transaction ID 가 부여되지 않아 Transaction ID 설정에 대한 오버헤드를 해결할 수 있다.

 

성능의 대한 이점도 있기 때문에 사용하는 것이 좋아보이며 혹시 위에 나열된 이점에 대해서 크게 해당하는 사항이 없더라도 코드 가독성이 좋아지므로 팀원들과 같이 명시적으로 두고 사용하는 것이 좋아보인다.

 

댓글