출처 :
@Transactional 어노테이션의 이해
나는 보통 서비스 코드에 @Transactional 어노테이션을 활용해준다. 그런데 사실 뜻도 잘 모르고 좋다고 그래서 쓴거라...지나고 보니 정확히 설명하기가 어려웠다. 그런고로, 해당 어노테이션의 작
kafcamus.tistory.com
예를 들어보자. 만약 내가 쇼핑 앱을 켜서 상품을 구매하려고 한다.
그런데 내가 결제를 하는 짧은 시간 사이에 아래와 같은 일이 벌어지면 어떨까?
- 해당 판매자가 상품의 가격을 바꿔버려서, 잘못된 금액이 결제됨
- 같은 상품을 다른 사람도 구매해서, 상품 재고는 1개인데 2명에게 결제됨
- 결제가 완료되기 직전에 네트워크가 끊겨서, 돈은 나갔지만 구매완료는 되지 않음
아무래도 황당할 수밖에는 없다.
위의 예외적 상황을 막기 위해서, 다음과 같은 조치가 필요할 것이다.
- 내가 결제중일 때에는 해당 상품의 정보를 바꿀 수 없게 함
- 내가 결제중일 때에는 해당 상품을 다른 사람이 결제하지 못하게 함
- 내 구매가 오류로 완료되지 않았다면, 결제된 금액을 환불 처리함
위의 조치사항을 좀 더 간략하게 정리하면, 아래와 같이 정리할 수 있다.
"결제는 다른 사람과 독립적으로 이루어지며, 과정 중에 다른 연산이 끼어들 수 없다.
오류가 생긴 경우 연산을 취소하고 원래대로 되돌린다. 성공할 경우 결과를 반영한다."
여기서 결제는 트랜잭션의 예시로 든 것이다. 트랜잭션 역시, 위의 원칙을 바탕으로 한다.
그래서 어떤 연산에 트랜잭션이 보장된다면, DB에서 의도치 않은 값이 저장되거나 조회되는 것을 막을 수 있다.
@Transactional 어노테이션
@Transactional은 클래스나 메서드에 붙여줄 경우, 해당 범위 내 메서드가 트랜잭션이 되도록 보장해준다.
선언적 트랜잭션이라고도 하는데, 직접 객체를 만들 필요 없이 선언만으로도 관리를 용이하게 해주기 때문.
특히나 SpringBoot에서는 선언적 트랜잭션에 필요한 여러 설정이 이미 되어있는 탓에, 더 쉽게 사용할 수 있다.
- 연산이 고립되어, 다른 연산과의 혼선으로 인해 잘못된 값을 가져오는 경우가 방지된다.
- 연산의 원자성이 보장되어, 연산이 도중에 실패할 경우 변경사항이 Commit되지 않는다.
위의 속성이 보장되기 때문에, 해당 메서드를 실행하는 도중 메서드 값을 수정/삭제하려는 시도가 들어와도 값의 신뢰성이 보장된다. 또한, 연산 도중 오류가 발생해도 rollback해서 DB에 해당 결과가 반영되지 않도록 할 수 있다. (위의 코드가 조회 코드가 와닿지 않을 수 있지만, 생성/수정/삭제 도중 오류가 발생한다고 생각해보자!!)
'Spring' 카테고리의 다른 글
Spring - MVC 패턴의 이해_HTTP 메시지(Response) (1) (0) | 2023.02.12 |
---|---|
Spring - 생성자 생성 어노테이션 (0) | 2023.01.28 |
Repository를 선언할 때 final을 붙이는 이유 (0) | 2022.11.23 |
추상 클래스와 인터페이스의 차이, 모듈의 뜻 (0) | 2022.11.23 |
Domain이란? (0) | 2022.11.21 |