@Slf4j
@RequiredArgsConstructor
@Service
public class ChallengeService {
//@Transactional
public void registerChallenge(User user, ChallengeDto.Create request) {
// 1. 새로운 챌린지를 생성
Challenge newChallenge = Challenge.builder()
...
.build();
// 2. 챌린지 DB에 저장
challengeRepository.save(newChallenge);
// 3. 챌린지를 생성한 유저를 통해 챌린저 객체 생성
Challenger leader = Challenger.builder()
...
.build();
// 4. 챌린저 DB에 저장
challengerRepository.save(leader);
// 5. 챌린지 초대 보내기
}
}
위와 같은 흐름을 가지고 있다고 가정해보자.
(2)에서 이미 챌린지 데이터를 DB에 저장을 했는데 갑자기 네트워크 장애 등 어떠한 원인으로 인해 나머지 로직이 수행되지 않았을 경우
이미 DB에 저장된 챌린지 데이터는 어떻게 해야할까?
여기서 트랜잭션
의 개념이 사용된다 !
모든 일련의 작업들이 성공적으로 완료되어야 결과를 적용하고 (커밋
), 어떤 작업에서 오류가 발생했을 때는 이전에 성공한 작업들을 포함하여 완전히 되돌리는 것 (롤백
)이 트랜잭션의 개념이다. 모든 작업들이 성공해야 최종적으로 데이터베이스에 저장된다.
스프링에서도 트랜잭션 처리를 지원하는 방식 중 하나로, @Transactional 어노테이션을 클래스나 메소드에 선언한다.
클래스나 메소드 위에 @Transactional이 선언되면, 트랜잭션 기능이 적용된 프록시 객체가 생성된다. 프록시 객체는 PlatformTransactionManager를 사용하여 트랜잭션을 시작하고, 정상 여부에 따라 Commit 또는 Rollback 한다.
일련의 작업들을 묶어서 하나의 단위로 처리하고 싶다면 @Transactional을 사용하자 !