Programming/Spring

@Transactional

Boxya 2025. 5. 23. 23:38

[KT] AIVLE SCHOOL 39일차

 

 

트랜잭션(Transaction)

  • @Transactional
    • Spring Framework는 @Transaction 어노테이션을 이용한 선언적 트랜잭션 처리를 지원
  • 트랜잭션(Transaction)은 여러 단계로 구성된 작업을 논리적으로 묶어서 하나의 논리적 단위로 처리하는 것을 의미
  • DB에서 트랜잭션은 하나의 작업을 안전하게 처리하도록 보장해 주는 것을 의미
  • @Transactional 어노테이션은 클래스나 메서드 레벨에 적용할 수 있음
  • 해당 어노테이션은 다양한 속성을 가지고 있음
    • Propagation
      • 기본적으로 존재하는 트랜잭션에 참여하거나 새로운 트랜잭션을 시작
    • Isolation:
      • 데이터베이스의 기본 격리 수준을 따르거나, 특정 격리 수준을 지정할 수 있음
    • ReadOnly:
      • 트랜잭션을 읽기 전용으로 설정해 데이터 변경을 방지하고 성능을 최적화
    • rollbackFor/noRollbackFor:
      • 특정 예외 발생 시 트랜잭션을 롤백하거나 롤백하지 않도록 설정
    • Timeout:
      • 트랜잭션의 최대 실행 시간을 초 단위로 설정하여 시간 초과 시 자동으로 롤백
  • 트랜잭션 설정
    • Spring에서 @Transactional을 사용하려면 @EnableTransactionManagement 어노테이션을 설정 클래스
      에 추가하고, 트랜잭션 관리자 빈을 등록해야 함
    • 일반적으로 'DataSourceTransactionManager'나 'JpaTransactionManager'를 사용
  • @Transactional 장점
    • 선언적 트랜잭션 관리
      • @Transactional을 활용하면 코드 내에서 트랜잭션 관리 로직을 분리할 수 있음
      • 이로 인해 비즈니스 로직에만 집중할 수 있으며, 코드의 가독성과 유지보수성이 향상됨
    • 일관성 있는 데이터 처리
      • 트랜잭션은 모든 작업이 성공적으로 완료되거나 실패할 경우 이전 상태로 돌아감
      • 이는 데이터의 무결성을 유지하는 데 중요
    • 간편한 롤백 처리
      • 예외 발생 시 Spring의 트랜잭션 관리가 자동으로 트랜잭션을 롤백
      • 개발자는 예외 발생 시 수동으로 롤백하는 복잡한 로직을 구현할 필요가 없음
    • 트랜잭션의 전파 및 격리 수준 제어
      • @Transactional 어노테이션으로 트랜잭션의 전파 동작과 격리 수준을
      • 지정할 수 있어, 다양한 트랜잭션 시나리오에 유연하게 대응할 수 있다.
  • @Transactional 사용 시 주의점
    • 프록시 기반 동작
      • Spring의 선언적 트랜잭션 관리는 프록시 기반으로 작동함
      • 이는 같은 클래스 내부에서 @Transactional 메소드를 직접 호출할 경우, 트랜잭션 처리가 적용되지 않을 수 있음
    • 예외 처리
      • 기본적으로 @Transactional은 런타임 예외와 에러 발생 시에만 롤백
      • 체크 예외에 대해서는 롤백이 발생하지 않으므로, 필요한 경우 rollbackFor 속성을 사용하여 명시적으로 롤백 조건을 설정해야 함
    • 트랜잭션 격리와 데드락
      • 높은 격리 수준을 설정하면 데드락의 발생 가능성이 증가할 수 있음
      • 반면, 낮은 격리 수준을 사용하면 다른 트랜잭션 문제(예: 더티 리드, 팬텀 리드)가 발생할 수 있음
      • 적절한 격리 수준을 선택하는 것이 중요
    • 성능 고려
      • @Transactional 어노테이션이 적용된 메소드는 트랜잭션 관리 오버헤드를 발생시킬 수 있음
      • 특히 읽기 전용 쿼리에서는 readOnly=true 설정을 사용하여 성능을 최적화할 수 있음
  • 트랜잭션의 속성
    • 트랜잭션의 특징은 크게 4가지로 구분
    • 원자성(Atomicity)
      • 트랜잭션의 모든 연산은 원자 단위로 처리되어야 함
      • 즉, 모든 연산이 성공적으로 수행되거나 실패한 경우, 트랜잭션 전체가 성공 또는 실패해야 함
    • 일관성 (Consistency)
      • 트랜잭션이 실행된 후에도 데이터베이스는 일관된 상태를 유지해야 함
      • → 즉, 트랜잭션이 시작 전과 끝난 후에도 데이터베이스의 무결성이 유지되어야 함
    • 고립성 (Isolation)
      • 여러 트랜잭션이 동시에 실행될 때 각 트랜잭션은 서로 영향을 미치지 않고 독립적으로 실행되는 것처럼 보장되어야 함
    • 지속성 (Durability)
      • 트랜잭션이 성공적으로 완료된 경우, 그 결과는 영구적으로 반영되어야 함
      • 즉, 시스템 장애 또는 다시 시작되어도 트랜잭션의 결과는 손실되지 않아야 함
    • 데이터베이스를 다룰 때 트랜잭션을 적용하면 데이터 추가, 갱신, 삭제 등으로 이루어진 작업을 처리하던 중 오류가 발생해도 모든 작업들을 원상태로 되돌릴 수 있음
    • 모든 작업들이 성공해야만 최종적으로 데이터베이스에 반영되도록 함
  • Spring에서 @Transactional을 이용해 트랜잭션 처리하기
    • DB와 관련된, 트랜잭션이 필요한 서비스 클래스 혹은 메소드에 @Transactional 어노테이션을 적용
    • 클래스와 메소드 모두 @Transactional 어노테이션을 적용한 경우 메소드 레벨의 @Transactional 선언이 우선 적용됨
    • @Transactional이 붙은 메소드는 포함하고 있는 작업 중에 하나라도 실패할 경우 전체 작업을 취소
  • @Transactional 주요 속성
    • 전파(Propagation) 속성
      • 트랜잭션 동작 도중 다른 트랜잭션을 호출하는 상황에 선택
      • PROPAGATION_MANDATORY
        • 작업은 반드시 특정 트랜잭션이 존재한 상태여야 가능
      • PROPAGATION_NESTED :
        • 기존에 트랜잭션이 있는 경우, 포함되어 실행됨
      • PROPAGATION_NEVER :
        • 트랜잭션 상황 하에 실행된다면 예외가 발생함
      • PROPAGATION_NOT_SUPPORTED :
        • 트랜잭션이 있는 경우엔 트랜잭션이 끝날때까지 보류된 후 실행됨
      • PROPAGATION_REQUIRED :
        • 트랜잭션이 있으면 그 상황에서 실행, 없으면 새로운 트랜잭션이 실행됨
      • PROPAGATION_REQUIRED_NEW :
        • 대상은 자신만의 고유한 트랜잭션으로 실행됨
      • PROPAGATION_SUPPORTS :
        • 트랜잭션을 필요로 하지 않으나, 트랜잭션 상황 하에 있다면 포함되어 실행됨
    • 격리(Isolation) 레벨
      • DEFAULT
        • DB 설정, 기본 격리 수준
      • • SERIALIZABLE
        • 가장 높은 수준의 격리, 성능 저하의 우려가 있음
      • • READ_UNCOMMITED
        • 커밋되지 않은 데이터에 대한 읽기를 허용
      • • READ_COMMITED
        • 커밋된 데이터에 대해 읽기만 허용
      • • REPEATEABLE_READ
        • 동일 필드에 대해 다중 접근 시 모두 동일한 결과를 보장
    • Read - Only 속성
      • • 트랜잭션을 읽기 전용으로 설정할 수 있음
      • • True인 경우 Insert, Update , Delete 실행 시 예외 발생, 기본 설정은 false
    • Rollback - for 예외
      • • 특정 예외가 발생 시 강제로 Rollback을 수행
    • No-Rollback - for - 예외
      • • 특정 예외의 발생 시에는 Rollback 처리되지 않음
    • Timeout 속성
      • 지정한 시간 내 해당 메소드 수행이 완료되지 않은 경우 rollback