티스토리 뷰

Spring

[Spring]@Transactional이란?

Xion 2020. 2. 10. 14:56

먼저, 트랜젝션의 성질은 다음과 같이 ACID 성질을 가지고 있습니다. (정처기에서 암기한 기억이..)

 

| 트랜잭션의 성질

 

1.원자성(Atomicity)

 - 한 트랜잭션 내에서 실행한 작업들은 하나로 간주. 즉, 모두 성공 또는 모두 실패. 

   즉, 여러번의 CRUD작업이 일어나면서 에러가 발생해도 데이터의 정합성을 지켜야 할 때가 있다.

 

2.일관성(Consistency)

 - 트랜잭션은 일관성 있는 데이타베이스 상태를 유지한다. (data integrity 만족 등.)

 

3.격리성(Isolation)

 - 동시에 실행되는 트랜잭션들이 서로 영향을 미치지 않도록 격리해야한다.

 

4.속성(Durability)

 - 트랜잭션을 성공적으로 마치면 결과가 항상 저장되어야 한다.



스프링에서 트랜잭션 처리 방법

  • -스프링에서는트랜잭션처리를 지원하는데 그중어노테이션 방식으로@Transactional을 선언하여 사용하는 방법이 일반적이며,선언적 트랜잭션이라 부릅니다.
  • -RuntimeException에 대해서만 롤백처리가 가능합니다.
  • -MySQL일 경우 Inno일때만 트랜잭션이 작동합니다.
  • -proxy를 사용할 때 반드시 public 메소드에 사용해야 합니다.
  • -클래스들이 인터페이스를 사용하는지 확인해야합니다.
     ( @Transactional 어노테이션 같은 경우에는 Spring AOP를 이용하는데 AOP는 기본적으로 Dynamic Proxy를 이용합니다.

    Dynamic Proxy는 인터페이스 기반으로 동작하기 때문에 인터페이스가 없을경우 트랜잭션이 동작하지 않습니다. )
  • -인터페이스없이 트랜잭션을 작동시키려면 CGLib Proxy를 사용하면됨(proxy-target-class="true")
  • ex) <tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true"/>

 

다음과 같은 2가지 방식으로 정의합니다.

-<tx:advice> 태그를 이용한 트랜잭션 처리

-@Transactional 어노테이션을 이용한 트랜잭션 설정

 

ex) 클래스 메서드 위에 @Transactional을 적어주면 이 클래스에 트랜잭션 기능이 적용된 프록시 객체가 생성됩니다.

    @Transactional(readOnly = true)
    public List<PostsListResponseDto> findAllDesc()
    {
        return jpaRepository.findAllDesc().stream()
                .map(PostsListResponseDto::new)
                .collect(Collectors.toList());
    }

이 프록시 객체는 @Transactional이 포함된 메소드가 호출 될 경우, PlatformTransactionManager를 사용하여 트랜잭션을 시작하고, 정상 여부에 따라 Commit 또는 Rollback 한다.

| 트랜잭션 사용 이유 ?

 

- DAO단에서 오류가 발생하면 쿼리를 자동 rollback 해주기 위해 사용됩니다.

단,

트랜잭션을 어느 Layer에서 사용할지 신중히 고민하여 선택해야 합니다.

트랜잭션이 발생하기 직전인 DB와 직접 연관이 있는 Layer 또는 트랜잭션 전에 조건을 준 로직이 담긴 Service Layer에서 사용하는 것이 좋겠습니다.