@Transactional
@Transactional 이란?
@Transactional은 클래스나 메서드에 붙여줄 경우, 해당 범위 내 메서드가 트랜잭션이 되도록 보장해준다
선언적 트랜잭션이라고도 하는데, 직접 객체를 만들 필요 없이 선언만으로도 관리를 용이하게 해주기 때문이다
특히나 SpringBoot에서는 선언적 트랜잭션에 필요한 여러 설정이 이미 되어있어 더 쉽게 사용할 수 있다
@Transactional(readOnly=true)가 꼭 필요한가?
써주는게 좋다!
why?
조회한 데이터를 return 한다고 해도
의도치 않게 데이터가 변경되는 일
을 사전에 방지해준다예상치 못한 Entity의 등록, 변경, 삭제 예방
Entity를
읽기 전용
으로 조회 시, 변경 감지를 위한 snapshot을 유지하지 않아도 되고, 영속성 컨텍스트를 flush 하지 않아도 돼 성능을 최적화 할 수 있다트랜잭션에
readOnly=true
옵션을 주면 스프링 프레임워크가 Hibernate session flush mode를 MANUAL로 설정한다이렇게 하면 강제로 플러시를 호출하지 않는 한 플러시가 일어나지 않는다!
따라서 트랜잭션을 커밋하더라도 영속성 컨텍스트가 플러시 되지 않아서 엔티티의 등록, 수정, 삭제이 동작하지 않는다
또한 읽기 전용으로 영속성 컨텍스트는 변경 감지를 위한 스냅샷을 보관하지 않으므로 성능이 향상된다
해당 옵션인 경우 CUD 작업이 동작하지 않고, 스냅샷 저장, 변경 감지(dirty check)의 작업을 수행하지 않아 성능이 향상된다
Dirty check
이란?상태 변경검사
영속성 컨텍스트와 연결됨
JPA에서는 트랜잭션이 끝나는 시점에 변화가 있는 모든 엔티티 객체를 데이터베이스에 자동으로 반영해준다
JPA에서는 엔티티를 조회하면 해당 엔티티의 처음 조회 상태 그대로 스냅샷을 만들어 놓는다
그리고 트랜잭션이 끝나는 시점에는 이 스냅샷과 비교해서 다른 점이 있다면 Update Query를 데이터베이스로 전달한다
MySQL
이중화 구성(Master - Slave)
시 DB가 master와 slave로 나누어져 있다면 readOnly = true로 있는 경우에는 읽기 전용으로 master가 아닌 slave를 호출하게 된다상황에 따라 DB 서버의 부하를 줄이고 약간의 최적화를 할 수 있다
@Transactional(readOnly=true) annotation 있다면 코드를 접하는 사람들이 직관적으로 보기에 해당 메서드는 READ에 대한 동작만 수행할 것이라고 예상할 수 있다
Spring @Transactional vs javax @Transactional
javax @Transactional
자바 표준 확장 패키지
자바에서 기본적으로 제공
Spring @Transactional
org.springframework에서 제공
Spring Container가 관리해준다
org.springframework.transaction.annotation.Transactional
을 사용해야 하는 이유많은 Option들을 제공한다
isolation
: the underlying database isolation levelnoRollbackFor
andnoRollbackForClassName
: the list of JavaException
classes that can be triggered without triggering a transaction rollbackrollbackFor
androllbackForClassName
: the list of JavaException
classes that trigger a transaction rollback when being thrownpropagation
: the transaction propagation type given by the[Propagation](https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/transaction/annotation/Propagation.html)
Enum. For instance, if the transaction context can be inherited (e.g.,REQUIRED
) or a new transaction context should be created (e.g.,REQUIRES_NEW
) or if an exception should be thrown if no transaction context is present (e.g.,MANDATORY
) or if an exception should be thrown if a current transaction context is found (e.g.,NOT_SUPPORTED
).readOnly
: whether the current transaction should only read data without applying any changes.timeout
: how many seconds should the transaction context be allowed to run until a timeout exception is thrown.value
ortransactionManager
: the name of the SpringTransactionManager
bean to be used when binding the transaction context.
Last updated