본문 바로가기

IT

@Transactional(readOnly = true) 사용법과 유의사항을 알아보자

728x90
반응형
728x170

Spring Framework에서 @Transactional(readOnly = true) 어노테이션 사용과 트랜잭션이 읽기 전용으로 수행되는 원리를 포함하여 사용법과 유의사항에 대하여 알아보겠습니다.

 

Spring Framework에서 제공하는 @Transactional(readOnly = true)는 데이터베이스 트랜잭션에서 읽기 작업만 수행되도록 합니다. 일반적으로 트랜잭션은 데이터베이스 작업을 논리적으로 그룹화하여 원자성, 일관성, 격리성, 지속성을 보장합니다. 트랜잭션 내에서 수행되는 작업은 읽기 작업과 쓰기 작업이 포함될 수 있습니다. 이렇게 설계된 이유는 여러 개의 트랜잭션에서 동시에 읽기 작업을 수행할 수 있기 때문에 성능이 향상될 수 있습니다. 하지만 모든 데이터베이스 작업이 읽기 전용으로 수행되는 것은 아니고, 필요한 경우 @Transactional 어노테이션의 속성을 통해 조정할 수 있습니다.

 

예시로, 쓰기 작업이 필요한 경우 @Transactional(readOnly = false) 혹은 @Transactional(readOnly = "false")로 설정하여 쓰기 작업을 허용할 수 있습니다. 반대로, 읽기 전용의 트랜잭션을 설정하면 일관성과 격리성을 유지하면서 성능을 개선할 수 있습니다. 또한 Spring Framework에서 XML 설정이나 Java Config를 사용해 모든 메서드에 자동으로 @Transactional(readOnly = true)를 적용하는 방법도 제공합니다.

 

예시로, 주문 처리하는 서비스 메소드에는 @Transactional(readOnly = false)를 사용하여 읽기 및 쓰기 작업이 가능하게 하며, 상품 조회 서비스 메소드에는 @Transactional(readOnly = true)를 사용하여 읽기 작업만 수행하도록 합니다.

 

따라서 적절한 트랜잭션 설정을 통해 데이터의 일관성과 격리성을 유지하고, 성능을 최적화할 수 있다. 이 기능은 주로 데이터 조회, 상품 정보 조회, 사용자 목록 조회 등 데이터베이스에서 조회를 할 경우 주로 사용되며, 성능 개선에 도움이 된다. 만약 데이터베이스 작업 중 읽기와 쓰기 모두 가능하게 하려면, @Transactional(readOnly = false)를 명시적으로 사용하거나 어노테이션을 붙이지 않아야 한다. 이렇게 함으로써 트랜잭션 내에서 쓰기 작업이 필요하지 않으며, 성능 향상을 위해 readOnly 속성을 true로 설정할 수 있습니다.

 

많은 분들이 그러면 Spring Framework에서 @Transactional를 자동으로 적용하는 방법이 있나요? 라고 질문하시는대요~

 

Spring에서 XML 설정이나 Java Config를 사용하여 모든 메서드에 자동으로 @Transactional(readOnly = true)를 적용하는 방법도 존재하며, 이 방법을 통해 원하는 데이터베이스 작업에 따라 트랜잭션 속성을절하게 설정할 수 있습니다. 이렇게 함으로써 여러 작업을 원자적으로 처리하면서 데이터 무결성을 보장할 수 있습니다.

 

Spring Framework에서는 XML 설정 또는 Java Config를 사용하여 모든 메소드에 자동으로 @Transactional을 적용하는 방법을 제공합니다. 

XML 설정을 사용하는 경우, <tx:annotation-driven/> 태그를 추가하고, 적용할 어노테이션을 설정할 수 있습니다. 

<tx:annotation-driven transaction-manager="transactionManager"/>


Java Config를 사용할 경우에는 @EnableTransactionManagement 어노테이션을 설정하고, TransactionManager Bean을 생성하여 사용할 수 있습니다.

@Configuration
@EnableTransactionManagement
public class AppConfig {
  //DataSource Bean 생성
  @Bean
  public DataSource dataSource() {
    //DataSource 설정 코드
  }

  //TransactionManager Bean 생성
  @Bean
  public PlatformTransactionManager transactionManager() {
    return new DataSourceTransactionManager(dataSource());
  }
}


이렇게 설정하면, 모든 @Transactional 어노테이션이 적용된 메소드는 트랜잭션 처리를 자동으로 수행합니다. 이를 통해, 개발자는 일일이 트랜잭션을 설정하거나 관리할 필요 없이 DB 트랜잭션 처리를 간단하게 구현할 수 있습니다.

 

실제로 @Transactional 어노테이션 을 사용할 때 가장 큰 이점이나 성능적인 효과는 요약하면 아래와 같습니다~

 

@Transactional 어노테이션을 적용하는 가장 큰 이점은 트랜잭션 내에서 일괄적으로 데이터에 접근할 수 있다는 점입니다. 이를 통해 동일한 트랜잭션 내에서 일관성 있는 데이터를 유지할 수 있게 되고, 트랜잭션 잠금 등의 기능을 사용하여 다양한 데이터베이스 이슈를 해결할 수 있습니다.

 

또한, @Transactional 어노테이션을 사용하면 스프링이 자동으로 트랜잭션을 처리하기 때문에 개발자가 트랜잭션 처리를 수동적으로 작성할 필요가 없습니다. 이를 통해 개발 생산성을 향상시킬 수 있으며, 일관성 있는 트랜잭션 처리를 보장할 수 있습니다.

 

그러나, 모든 상황에서 @Transactional 어노테이션을 사용하는 것이 무조건적인 성능 개선을 보장하는 것은 아닙니다. 일부 경우에는 오히려 트랜잭션 처리 비용이나 오버헤드가 발생할 수 있습니다.

 

예를 들어, 조회만 하고 수정 작업이 없는 트랜잭션 내에서는 일관성 유지를 위해 트랜잭션 처리 비용이 쓸데없이 발생하게 됩니다. 이 경우에는 @Transactional(readOnly=true)와 같이 읽기 전용 트랜잭션 설정을 해주면 성능 개선 효과를 얻을 수 있습니다.

 

또한, 여러 메소드에서 트랜잭션을 롤백하는 경우, 롤백 처리의 영향 범위가 클수록 데이터베이스 전체에 잠금이 걸리게 되어 성능 저하를 발생시킬 수 있습니다. 이런 경우 어노테이션의 속성으로 propagation을 설정하여 트랜잭션 처리의 효율성을 높일 수 있습니다.

 

따라서, @Transactional 어노테이션을 사용하여 성능 개선을 위해 트랜잭션 처리를 구현할 때에는 각 상황에 따라 적절한 속성을 설정하는 것이 중요합니다. 이를 통해, 목적에 맞는 성능 향상을 도모할 수 있습니다.

 

마지막으로 하나만 더 말해보자면~

@Transactional을 사용할 때 영향을 미치는 요소는 다음과 같습니다.

1. 트랜잭션 범위: 트랜잭션 범위가 커질수록 처리 비용이 증가하게 됩니다. 트랜잭션 범위는 잘 판단하여 적절하게 처리해야 합니다.

2. 격리 수준: 트랜잭션에 사용되는 격리 수준이 높을수록 데이터베이스의 락이 많이 걸리므로 성능에 영향을 미칩니다. 따라서, 꼭 필요한 경우가 아니라면 격리 수준을 낮추는 것이 좋습니다.

3. 동시성 레벨: 최적의 동시성 레벨을 설정하지 않으면 성능에 영향을 미칩니다. 가장 효율적인 레벨을 찾기 위해 잘 튜닝해야 합니다.

4. 데이터 양: 하나의 트랜잭션에서 처리하는 데이터양이 많을수록 처리 비용이 증가합니다.

5. 트랜잭션 제어 방식: 세밀한 트랜잭션 제어를 위해서는 프로그래머가 @Transactional을 사용하여 트랜잭션 범위를 지정해야 합니다. 그러나 오히려 성능 저하를 일으킬 수 있으므로 필요한 경우에만 사용하는 것이 좋습니다.

6. 예외 처리: 예외가 발생하면 롤백이 발생하고 성능에 영향을 미치게 됩니다. 따라서, 예외 처리를 최대한 줄이는 것이 좋습니다.

7. 적절한 트랜잭션 타입 선택: @Transactional 어노테이션을 사용할 때 적절한 트랜잭션 타입을 선택해야 합니다. 필요한 경우 readOnly, requires_new 등 속성을 설정하여 트랜잭션 처리 효율을 높일 수 있습니다.

8. DBMS 설정: DBMS 설정을 최적화하여 성능을 개선할 수 있습니다.

각 요소들은 서로 영향을 주고받으며, 최적의 조합을 찾아 성능을 향상시켜야 합니다. 어떤 것이 중요한지 파악하고 그 요소를 최적화하여 성능에 영향을 미치지 않도록 해야 합니다.

728x90
반응형
그리드형