데이터베이스 트랜잭션은 데이터베이스 관리 시스템 또는 유사한 시스템에서 상호작용의 단위이다.
여기서 단위라는 말을 사용했는데, 쉽게 말하면 더 이상 쪼개질 수 없는 최소의 연산이라는 의미가 된다.
예를 들어보자. 만약 내가 쇼핑 앱을 켜서 상품을 구매하려고 한다.
그런데 내가 결제를 하는 짧은 시간 사이에 아래와 같은 일이 벌어지면 어떨까?
아무래도 황당할 수밖에는 없다.
위의 예외적 상황을 막기 위해서, 다음과 같은 조치가 필요할 것이다.
위의 조치사항을 좀 더 간략하게 정리하면, 아래와 같이 정리할 수 있다.
"결제는 다른 사람과 독립적으로 이루어지며, 과정 중에 다른 연산이 끼어들 수 없다.
오류가 생긴 경우 연산을 취소하고 원래대로 되돌린다. 성공할 경우 결과를 반영한다."
여기서 결제는 트랜잭션의 예시로 든 것이다. 트랜잭션 역시, 위의 원칙을 바탕으로 한다.
그래서 어떤 연산에 트랜잭션이 보장된다면, DB에서 의도치 않은 값이 저장되거나 조회되는 것을 막을 수 있다.
1. 원자성(Atomicity)
한 트랜잭션 내에서 실행한 작업들은 하나로 간주한다. 즉, 모두 성공 또는 모두 실패
2. 일관성(Consistency)
트랜잭션은 일관성 있는 데이타베이스 상태를 유지한다. (data integrity 만족 등.)
3. 격리성(Isolation)
동시에 실행되는 트랜잭션들이 서로 영향을 미치지 않도록 격리해야한다.
4. 지속성(Durability)
트랜잭션을 성공적으로 마치면 결과가 항상 저장되어야 한다.
@Transactional은 클래스나 메서드에 붙여줄 경우, 해당 범위 내 메서드가 트랜잭션이 되도록 보장해준다.
선언적 트랜잭션이라고도 하는데, 직접 객체를 만들 필요 없이 선언만으로도 관리를 용이하게 해주기 때문.
특히나 SpringBoot에서는 선언적 트랜잭션에 필요한 여러 설정이 이미 되어있는 탓에, 더 쉽게 사용할 수 있다.
@Transactional 어노테이션을 기준으로 설명하자면.
트랜잭션은 Spring AOP를 통해 구현되어있다.
더 정확하게 말하면, 어노테이션 기반 AOP를 통해 구현되어있다. (import문을 보면 알 수 있다)
import org.springframework.transaction.annotation.Transactional;
DB와 관련된, 트랜잭션이 필요한 서비스 클래스 혹은 메서드에 @Transactional 어노테이션을 달아주면된다.
클래스, 메서드 모두에 @Transactional 어노테이션을 붙이면 메서드 레벨의 @Transactional 선언이 우선 적용된다.
@Transactional이 붙은 메서드는 메서드가 포함하고 있는 작업 중에 하나라도 실패할 경우 전체 작업을 취소한다.