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:
- 트랜잭션의 최대 실행 시간을 초 단위로 설정하여 시간 초과 시 자동으로 롤백
- Propagation
- 트랜잭션 설정
- Spring에서 @Transactional을 사용하려면 @EnableTransactionManagement 어노테이션을 설정 클래스
에 추가하고, 트랜잭션 관리자 빈을 등록해야 함 - 일반적으로 'DataSourceTransactionManager'나 'JpaTransactionManager'를 사용
- Spring에서 @Transactional을 사용하려면 @EnableTransactionManagement 어노테이션을 설정 클래스
- @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
- 동일 필드에 대해 다중 접근 시 모두 동일한 결과를 보장
- DEFAULT
- Read - Only 속성
- • 트랜잭션을 읽기 전용으로 설정할 수 있음
- • True인 경우 Insert, Update , Delete 실행 시 예외 발생, 기본 설정은 false
- Rollback - for 예외
- • 특정 예외가 발생 시 강제로 Rollback을 수행
- No-Rollback - for - 예외
- • 특정 예외의 발생 시에는 Rollback 처리되지 않음
- Timeout 속성
- 지정한 시간 내 해당 메소드 수행이 완료되지 않은 경우 rollback
- 전파(Propagation) 속성