[Spring] Transactional 어노테이션

그냥 준현·2024년 7월 18일
0

Computer Science

목록 보기
12/16

스프링(Spring)의 @Transactional 어노테이션은 스프링에서 쉽게 트랜잭션(Transaction) 설정을 할 수 있게 도와줍니다.

1. 선언적 트랜잭션

@Transactional 어노테이션은 선언적 트랜잭션(Declarative Transaction Management)의 한 종류입니다.

선언적 트랜잭션이란,
트랜잭션 처리를 코드 내에서 직접 제어하지 않고, 트랜잭션의 경계를 선언적으로 정의하는 방식
트랜잭션 처리를 더 간편하고 명확하게 수행

또 다른 선언적 트랜잭션 방법으로는 xml 파일을 이용할 수 있습니다.
이 글에서는 @Transactional 어노테이션을 이용하는 방법만 살펴보겠습니다.

2. 사용 예시

@Service
public class MyService {

    @Autowired
    private JdbcTemplate jdbcTemplate;

	// transaction을 설정하고 싶은 메서드에 어노테이션 추가
    @Transactional
    public void performTransactionalOperation() {
        jdbcTemplate.update("INSERT INTO my_table (column1, column2) VALUES (?, ?)", "value1", "value2");
    }

	// transaction을 설정하고 싶은 메서드에 어노테이션 추가
    @Transactional(readOnly = true)
    public String getTransactionalData() {
        return jdbcTemplate.queryForObject("SELECT column1 FROM my_table WHERE column2 = ?", new Object[]{"value2"}, String.class);
    }
}

3. 파라미터

위와 같은 parameter가 있으면 하나씩 기능을 살펴보겠습니다.

3.1 transactionManager

트랜잭션 기능은 JDBC, JPA, Hibernate, JTA 등 어떤 API를 사용하느냐에 따라 구현 방식이 달라집니다.
Spring은 여러 트랜잭션 관리자를 지원하며 @Transactional 어노테이션의 transactionManager 파라미터로 어떤 관리자를 사용할 지 지정합니다.

그리고 Spring은 PlatformTransactionManager라는 인터페이스로 트랜잭션 관리 기능을 추상화하여 정의합니다.

3.2 propagation

propagation을 설명하기에 앞서 물리 트랜잭션, 논리 트랜잭션이 무엇인지 알아봅시다.

3.2.1 물리 트랜잭션

데이터베이스에서 실제 실행되는 트랜잭션

데이터베이스의 Connection을 통해 실제 Commit과 Rollback 연산을 수행합니다.

3.2.2 논리 트랜잭션

애플리케이션 레벨에서 관리되는 트랜잭션

쉽게 얘기하면 하나의 @Transactional 어노테이션이 하나의 논리 트랜잭션이 됩니다.

3.3.3 전파 옵션

그러면 위 그림처럼 service와 repository에 각각 @Transactional 어노테이션이 선언되어 있다고 생각해봅시다.

service가 호출되면서 트랜잭션을 수행하다가 repository 호출로 인해 새로운 논리 트랜잭션을 실행하게 됩니다.
이때, 물리 트랜잭션을 어떻게 할 것이냐 하는 문제가 발생합니다.

전파(propagation)은 메서드가 호출될 때 기존 물리 트랜잭션을 사용할지, 새로운 물리 트랜잭션을 시작할지, 또는 트랜잭션 없이 실행할지를 결정하는 스프링 트랜잭션 관리 설정입니다.

전파 관련 옵션을 다음과 같습니다.

  • REQUIRED
  • SUPPORTS
  • MANDATORY
  • REQUIRES_NEW
  • NOT_SUPPORTED
  • NEVER
  • NESTED

이 중 가장 대표적인, REQUIREDREQUIRES_NEW를 살펴보겠습니다.
나머지는 이 둘의 응용이므로 좀만 생각해보면 이해가 되실겁니다.

3.3.3.1 REQUIRED

앞서 본 그림이 REQUIRED 상황입니다.
REQUIRED는 다음과 같이 동작합니다.

  • 기존 물리 트랜잭션 X: 새로운 물리 트랜잭션 생성
  • 기존 물리 트랜잭션 O: 기존 물리 트랜잭션에 참여

repository로부터 실행된 새로운 논리 트랜잭션은 기존 service로부터 생성된 물리 트랜잭션에 참여했습니다.

3.3.3.2 REQUIRES_NEW

REQUIRES_NEW는 다음과 같이 동작합니다.

  • 기존 물리 트랜잭션 X: 새로운 물리 트랜잭션 생성
  • 기존 물리 트랜잭션 O: 새로운 물리 트랜잭션 생성

repository로부터 실행된 새로운 논리 트랜잭션은 service와는 별도로 물리 트랜잭션에 생성했습니다.

3.4 isolation

'격리 수준'을 설정하는 파라미터입니다.
이와 관련해서는 이 게시물에 자세히 설명해놓았습니다.

3.5 readOnly

해당 트랜잭션이 읽기 전용인지 설정합니다.
select 쿼리문만 사용하는 트랜잭션에서 readOnly를 적용하면, JPA를 사용할 때 성능이 개선된다고 합니다.

3.6 timeout

트랜잭션 timeout을 설정합니다.

3.7 rollbackFor

스프링은 기본적으로 RuntimeException과 Error 상황에 대해 Rollback을 수행합니다.
하지만 rollbackFor을 설정해 특정 checked/unchecked exception에 대해 rollback을 수행하도록 지정할 수 있습니다.

3.8 noRoolbackFor

rollbackFor와 반대로 noRollbackFor을 설정해 특정 checked/unchecked exception에 대해 rollback을 수행하지 않도록 지정할 수 있습니다.

profile
잘해야 재밌어

0개의 댓글

관련 채용 정보