@Transactional
트랜잭션 2가지 방법
어노테이션 이용
AOP
여기선 어노테이션 @Transactional 을 사용하는 방법과 주의할 점에 대해 알아보자.
설정
@Configuration
@EnableTransactionManagement // 스프링 3.1에 등장 어노테이션
public class PersistenceJPAConfig{
@Bean
public LocalContainerEntityManagerFactoryBean
entityManagerFactory(){
//...
}
@Bean
public PlatformTransactionManager transactionManager(){
JpaTransactionManager transactionManager
= new JpaTransactionManager();
transactionManager.setEntityManagerFactory(
entityManagerFactory().getObject() );
return transactionManager;
}
}Spring Boot 의 경우에는 클래스 패스에 있는 spring-data-* 나 spring-tx 가 트랜잭션 관리 설정 역할을 대신해준다.
@Transactional 어노테이션
설정 가능 옵션
Propagation 타입
isolation Level 레벨: 동시에 발생된 트랜잭션에 의해 적용된 변경 사항이 서로에게 어떻게 보이는지 설정
READ_UNCOMMITED(커밋되지 않은 읽기)
문제점: DIRTY READ
READ_COMMITTED(커밋된 읽기
문제점: NON-REPEATABLE READ
설명: 트랜잭션1에서 조회후 트랜잭션1에서 다시 읽었는데 다른 데이터값. 트랜잭션2에서 그 사이 변경해버렸다.
REPEATABLE_READ(반복 가능한 읽기)
문제점: PHANTOM READ
설명: 트랜잭션1에서 5개 데이터 나왔는데 다시 조회하니 6개. 트랜잭션2에서 그사이 추가해버렸다.
위에는 다른 트랜잭션에서 수정시 발생했고 이번에는 추가시 발생.
SERIALIZABLE (직렬화가능)
Timeout 설정
readOnly 플래그
Rollback 룰
2가지 방법
어노테이션 방법
@Transactional(rollbackFor = { SQLException.class })명시된 예외일 경우 롤백 처리
noRollbackFor 도 있음
프로그래머틱 방법
사용 비추
아래는 클래스 레벨에 적었는데, 메소드 레벨에서도 작성이 가능하다. interface 에도 지정 가능하다.
주의 사항
Transactions 과 Proxies
Spring은 @Transactional 이 달린 모든 class 또는 method 에 대해 프록시를 생성
전 후로 트랜잭션 로직 (begin & commit) 발동 시킴
자체 호출은 트랜잭션 작동 x (즉, 프록시가 들어오는 외부 메서드 호출만 가로채게 됩니다)
public 메서드만 @Transactional 사용 가능
인터페이스에 @Transactional를 지정하는 것을 비추하지만, Spring Data 의 @Repository 같은 경우 에는 수용된다.
참고자료
https://www.baeldung.com/transaction-configuration-with-jpa-and-spring
https://www.baeldung.com/spring-transactional-propagation-isolation
Last updated