Spring Data JPA - Transaction

Spring Data JPA

백기선님의 강의인 Spring Data JPA 강의를 듣고 공부한 내용을 정리한 글

@Transactional

이 부분은 사실 스프링 프레임워크의 Transaction의 기능을 JPA에서도 제공한다.

기본적으로 JPA가 사용하는 모든 메소드에는 기본적으로 @Transactional이 적용되어 있다.

스프링 프레임워크에서는 클래스에 걸린 애노테이션과 메소드에 같은 애노테이션이 적용되어 있다면

메소드에 적용된 애노테이션이 우선순위가 더 높다. (오버라이딩 해버림)

그렇다면 이 트랜잭션 애노테이션에 적용된 메소드는 언제 롤백이 될까?

그것은 바로 RuntimeException이나 Error가 발생할 때 롤백을 수행한다.

단, checked exception이 발생했을 때는 롤백을 수행하지 않는다.

그런데 만약 특정 RuntimeException에서는 롤백을 하지 않았으면 하는 바램이 있을 수도 있다.

그 때 사용할 수 있는 옵션이 noRollbackFornoRollbackForClassName이다.

transactionManager 옵션을 설정할 수도 있는데 이는 JPA에서 제공하는 TransactionManager를 사용하면 되기 때문에 건드릴 필요가 없는 옵션이다.

조금 어려운 옵션이 isolation과 propagation이다.

isolation은 여러 개의 트랜잭션이 들어왔을 때 이들을 어떻게 처리할 것인가에 대한 것이다.

readUncommited, readCommited, repeatableRead, Serializable 총 4개의 옵션이 존재한다.

기본 isolation level은 Default인데 이는 사용하는 DB에서 기본적으로 제공하는 레벨을 따른다.

기본적으론 isolation level이 대게 readCommited이다.

propagation은 어떻게 트랜잭션을 전파시킬 것인가에 대한 내용이다.

만약 트랜잭션이 적용된 하나의 메소드 안에서 트랜잭션이 적용된 메소드를 호출하는 경우 (nested) 트랜잭션을 같이 가져갈 것인지 따로 가져갈 것인지에 대한 내용이다. (토비의 스프링3에 이 내용이 잘 나와있다고 하니 스터디 열심히 해야겠다.)

readOnly는 약간의 성능 향상을 노려볼 수 있는 옵션인데, 데이터를 바꾸지 않는 경우라면 가급적이면 readOnly 옵션을 true로 주도록 하자.

JPA Hibernate를 사용할 때 readOnly를 사용하면 좋은 점에 대해 구체적으로 알아보자.

레퍼런스를 보면 FLUSH 모드를 NEVER로 설정하여 Dirty Checking을 하지 않아서 성능이 향상될 수 있다고 한다.

FLUSH 모드는 언제 DB에 싱크를 할 것이냐에 관한 설정이다.

기본값은 적절한 타이밍에 되게 되어있다. 데이터를 read하기 전, commit하고 난 이후에 보통 FLUSH를 한다.

이 FLUSH 옵션을 NEVER로 설정한다는 것은 내가 지금 현재 Persistence 상태의 도메인 객체들의 상태가 변경될 일이 없으니 나는 더티 체킹을 하지 않겠다라는 것이다.

그러면 select를 할 때 의미없는 FLUSH가 발생하지 않으니 성능 향상을 꿰할 수 있다.

Reference

인프런 백기선님의 스프링 Data JPA



© 2022. by minkuk

Powered by minkuk