3.7.2 트랜잭션 in Spring

yeonseong Jo·2023년 7월 7일
0

SEB_BE_45

목록 보기
40/47
post-thumbnail

Spring Data JPA는
Repository를 통해 save하거나 find하는데,
이 과정중에 트랜잭션 처리를 어떻게 하는지는
겉으로 보이지 않았다

그래서,
Spring에서 트랜잭션을 관리하는 것에 대해
자세히 알고자 한다.


transaction in spring

바닐라 JPA를 사용했을 때
EntityFactory로 부터 EntityManager를 생성하고,
생성한 manager에서 EntityTransaction을 가져와
data를 save하거나 find했었다.

이 방식처럼 Spring Boot를 사용하지 않는다면,

@Configuration
@EnableTransactionManagement
public class JpaConfig{
	@Bean
    public LocalContainerEntityManagerFactoryBean entityManagerFactoryBean(){
    	final LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
        ...
        return em;
    }
    ...
    @Bean
    public PlatformTransactionManager transactionManager(){
    	JpaTransactionManager tx = new JpaTransactionManager();
        tx.setEntityManagerFactory(entityManagerFactoryBean().getObject());
        return tx;
    }
}

Configuration을 통해
EntityManagerFactoryTransactionManager
Bean으로 등록하여 사용한다.

Transactional

SpringBoot를 사용하고 있다면, 와 같은 트랜잭션 설정을
내부적으로 알아서 해주기 때문에

@Service
@Transactional
public classs EntityService{
	...
    public Entity createEntity(Entity entity){
    	return repository.save(entity);
    }
    ...
}

트랜잭션이 필요한 클래스에 (보통은 service)
@Transactional annotation을 사용하여 적용한다.

참 간단하다
EntityManagerEntityTransaction으로
try/catch를 사용해서 rollback시키는 방법과 비교했을 때
단 한줄만으로 트랜잭션 관리가 이루어지는 것이다.

@Service
@Transactional
public classs EntityService{
	...
    @Transactional(readOnly=True)
    public Entity findEntity(long id){
    	return repository.findById(id);
    }
    ...
}

각 메서드 별로 @Transactional annotation을 설정해
위와 같이 readOnly 같이 세부 설정도 가능한거 같다.

propagation

만약 별도의 설정값 없이
@Transactional annotation이 있는 메서드에서
@Transactiona인 다른 메서드를 사용하는 상황이 있을 때
호출하는 메서드에서 오류가 생겨 rollBack 시
호출 당하는 메서드도 rollBack 된다.

이렇게 여러 트랜잭션을 묶어
하나의 트랜잭션 경계로 만들 수 있는데,
트랜잭션 경계에서 다음 트랜잭션을
어떻게 진행할지 결정하는 것이 propagation이다.

REQUIRED

default값으로
진행중인 트랜잭션이 없으면 새로 시작하고,
있다면 해당 트랜잭션에 참여한다.

REQUIRES_NEW

진행중인 트랜잭션과 무관하게
트랜잭션이 새로 시작되며
기존 트랜잭션은 새로 시작된 트랜잭션이 종료할 때 까지
중지하게 된다.

MANDATORY

진행중인 트랜잭션이 없으면 예외를 발생

NOT_SUPPORTED

트랜잭션이 필요하지 않음을 뜻하고
만약 진행중인 트랜잭션이 있으면 NOT_SUPPORTED로 설정한 메서드가 종료될 때 까지 중지된다.

NEVER

트랜잭션이 필요하지 않고,
만약 진행중인 트랜잭션이 있으면 예외를 발생

isolation

트랜잭션의 ACID원칙 중 I원칙에 따라
각 트랜잭션은 서로 독립적으로 실행되는데,
@Transactional에서 isolation을 통해
트랜잭션간 간섭 정도를 변경할 수 있다.

READ_UNCOMMITED

다른 트랜잭션에서 아직 commit하지 않은 데이터를 읽을 수 있음

READ_COMMITED

다른 트랜잭션에서 commit한 데이터를 읽을 수 있음

REPEATABLE_READ

트랜잭션 내에서 한 번 조회한 데이터를 반복해서 조회해도 같은 데이터가 조회되도록 한다.

SERIALIZABLE

동일한 데이터에 대해 동시에 두 개 이상의 트랜잭션에서 관리하지 못하도록 한다.

이러한 isolation 설정값이 존재하기는 하나,
보통은 DB에 설정된 level을 따르는 것이 권장된다고 하여
DEFAULT값을 사용한다고 한다.

profile
뒤(back)끝(end)있는 개발자

0개의 댓글