트랜잭션

스프링 프레임워크에 관련된 내용이다. 기본적으로 모든 repository는 기본적으로 트랜잭션이 적용되어 있다.(repository 구현체인 SimpleJpaRepository에 @Transactional이 적용되어 있기 때문이다.)

@Transactional

repository나 service계층(repository를 사용하는 계층)에서 사용된다. 기본적으로 RuntimeException이나 error가 발생하면 해당 트랜잭션을 롤백시킨다. Checked Exception에는 롤백이 일어나지 않는다.

여러가지 옵션을 줄 수 있다.

readOnly: 데이터를 변경하는 operation이 없는 경우 true로 설정해주는 것이 좋다.

Isolation: 여러개의 트랜잭션이 동시에 데이터베이스에 접근했을때, 해당 트랜잭션들을 어떻게 처리할 것인지에 대한 설정(동시에 처리할 것인지, 하나 하나 처리할 것인지 등) 기본값은 default로 DB의 기본값을 따라간다.(대부분 READ_COMMITTED 방식이 default값이다.)

Propagation: 트랜잭션을 어떻게 전파시킬 것인지에 관한 것이다. 예를 들어 @Transactional을 가지고 있는 메서드가 있고, 그 메서드 안에서 다른 메서드를 호출했는데 그 메서드도 @Transactional을 가지고있는 경우, 첫 번째 메서드가 가지고 있던 트랜잭션을 두 번째 메서드가 이어갈 것이냐, 두 번째 메서드 자체에서 트랜잭션을 만들어서 따로 사용할 것이냐를 결정하는 것이다.(nested transaction에 관한 내용)

TIP

JPA 구현체로 Hibernate를 사용할 때, 트랜잭션을 readOnly로 사용하면 좋은점이 있다.

flush모드를 NEVER로 설정해줘서, 해당 트랜잭션안에서는 Dirty checking을 하지 않게 해준다.

flush모드: 데이터베이스와 sync를 맞춰주는 모드. 즉 언제 데이터베이스에 sync를 할 것인지에 관한 것이다. 기본값은 보통 커밋하거나 데이터를 가져오기 전에 flush하게 되어있다.

Dirty checking: 트랜잭션 내에서 변경이 일어날 시, PersistanceContext가 변경을 감지하여 데이터베이스에 반영하는 것

데이터를 읽어올 것이 많은 경우, DirtyChecking을 꺼놓으면 성능이 많이 올라간다.

Ex. findById 같은 경우 데이터를 읽어오기만 하기 때문에, readOnly 해주는 것이 좋다.(데이터 변경이 일어나지 않을 것이므로)

@Transactional(readOnly=true)
<T> List <T> findByPost_Id(Long id, Class<T> type);

0개의 댓글