이전에 Java&Oracle 편에서 Transaction에 대하여 알아보았습니다!
https://pabeba.tistory.com/139
이번에도 비슷한 예시를 보여드리려고 합니다.
TRANSACTION (@Transactional)
더 이상 나눌 수 없는 작업단위, 데이터베이스의 상태를 변경시키기 위해 수행하는 업무단위입니다.
Spring Boot 에서는 트랜젝션 동작이 필요한 메서드 위에 @Transactional 어노테이션만 작성하면 됩니다.
역시 예시를 들어야 이해가 빠를 것 같습니다.
예시
아이디 등록 시 작업 단위를 나눠보면 이렇습니다.
(아이디 등록 + 포인트 등록) = 아이디 생성 Transaction
@Service
@RequiredArgsConstructor
@Slf4j
public class MemberServiceImpl implements MemberService {
private final MemberMapper memberMapper;
private final PointMapper pointMapper;
@Transactional
@Override
public void register(MemberVO memberVO,PointVO pointVO) {
memberMapper.register(memberVO);
log.info("member 등록 {}",memberVO);
// pointVO.setId(null);//테스트를 위해 고의로 문제를 발생
pointMapper.register(pointVO);
log.info("point 등록 {}",pointVO);
}
}
이렇게 Service Class를 하나 생성하고 register 메서드를 생성해 줍니다.
1. Service Class를 생성할 때 @Service, @RequiredArgsConstructor를 설정해 줍니다.
@RequiredArgsConstructor를 설정해 주는 이유는 final 매개변수 생성자를 정의해 주기 위해서입니다.
❓왜 final을 사용하여 mapper 객체를 불러올까요?
- 불변성(Immutability)을 보장: final 키워드를 사용하면 한 번 할당된 값은 변경되지 않습니다. 의존성 주입 후에 해당 멤버 변수를 다른 객체로 다시 할당하거나 수정하는 것이 불가능해집니다. 이는 런타임 중에 의도치 않은 변경을 방지하고 안정성을 높입니다.
- 코드 안정성 향상: final 키워드를 사용하면 컴파일러가 초기화 이후에 해당 변수에 대한 잘못된 변경 시도를 컴파일 단계에서 감지할 수 있습니다. 이로 인해 코드 안정성이 향상됩니다.
- Thread-Safe 보장: 멀티스레드 환경에서 **final**로 선언된 변수는 해당 변수에 대한 동시 수정을 방지합니다. 이를 통해 스레드 간의 경쟁 조건과 동기화 문제를 방지하고, 더 안정적인 프로그램을 작성할 수 있습니다.
- 코드 가독성 증가: final 키워드를 사용하면 해당 변수가 의존성 주입 후에 변경되지 않는다는 것이 코드에서 명확하게 드러납니다. 이는 코드 가독성을 높여줍니다.
- 의도 표현: final 키워드를 사용하여 해당 변수가 의존성 주입을 위해 생성자를 통해 할당되는 것임을 명확히 표현할 수 있습니다. 이는 해당 멤버 변수가 어떤 방식으로든 다른 곳에서 변경되지 않음을 명시적으로 보여주는 것입니다.
2. @Transactional 어노테이션을 이용하여 동작의 중간에 Error 나 RuntimeException 계열 Exception 이 발생하면 진행되었던 모든 작업이 rollback 됩니다.
-> 테스트를 위해 위에 주석처리한 코드를 복구시키고 실행해 보면 아이디가 생성되지 않음을 알 수 있습니다.
주석을 풀고 이렇게 해서 회원등록을 실행해 보겠습니다.
역시 에러가 나는군요. id의 값이 null 값이라 포인트 등록에 대한 SQL 문이 작동하지 않을 것입니다.
포인트 부분에서 에러가 난 것이지만 아이디조차도 만들어지지 않아야만 Transaction 이 잘 작동했다고 할 수 있습니다. 확인해 볼까요?
cookie를 검색해도 회원정보가 나오지 않습니다.
이렇게 하나라도 제대로 동작되지 않으면 모든 동작을 뒤로 돌려서 하지 않은 상태로 만들 수 있는 기능입니다.
소감
리스크를 최소화하고 자신을 지켜야 한다고 생각이 드는 하루입니다. 하지만 걱정이 많아지면 삶을 살아가기 힘들어지기 때문에 조금은 지나친 걱정도 내려놔야 한다고 생각합니다.
자신이 생각하는 걱정은 또 지나 보면 아무것도 아닌 것이 되고 그러더라고요. 또한 자신이 생각하는 걱정이 현실이 되는 경우가 그렇게 크지 않고, 만일 현실이 되더라도 솟아날 구멍이 있을 것이라고 생각합니다.