Spring MVC 트랜잭션

김병수·2022년 11월 9일
0
post-thumbnail

트랜잭션

여러개의 작업들을 하나의 그룹으로 묶어서 처리하는 단위이다. 물리적으로는 여러 개의 작업이지만 논리적으로는 마치 하나의 작업으로 인식한다. 트랜잭션의 특징으로 영어 앞 글자를 축약하여 ACID 원칙이라고도 부른다.

ACID 원칙

원자성(Atomicity)
작업을 더이상 쪼갤 수 없을을 의미한다. 논리적으로 물리적인 여러 작업을 하나로 인식하기 때문에 전부 반영되거나 반영되지 않아야(All or Nothing) 한다.

일관성(Consistancy)
트랜잭션이 성공적으로 완료될 경우, 비즈니스 로직에서 의도하는대로 일관성있게 저장되거나 변경되어야한다. 예를 들어 회원이 커피 3잔을 주문 후 스탬프 횟수가 3 증가한 값으로 저장되있을거라 예상했는데, 3이 아닌 숫자로 증가한 값이 조회 된다면 일관성을 위배한 것이다.

고립셩(Isolation)
여러 개의 트랙잭션이 실행될 경우 각각 독립적으로 실행이 되어야 한다. 트랜잭션 밖에서는 어떤 연산도 중간 단계의 데이터를 볼 수 없다.

지속성(Durability)
성공적으로 수행된 트랜잭션은 영구히 반영되어야 한다. DB가 종료되어도 데이터는 물리적인 저장소에 지속적으로 유지되어야 한다.

트랜잭션 커밋(commit), 롤백(rollback)

커밋(commit)
트랜잭션 작업을 최종적으로 DB에 반영하는 명령어로, DB에 데이터를 영구적으로 저장한다. commit 명령을 수행하지 않으면 작업 결과가 DB에 최종적으로 반영되지 않고, 명령을 수행하면 하나의 트랜잭션 과정이 종료된다.

롤백(rollback)
트랜잭션 작업 중 문제 발생 시, 수행된 작업들을 취소한다. 따라서 트랜잭션 시작 이전의 상태로 돌아간다.

Spring에서의 트랜잭션

Spring에서 트랜잭션을 적용하는 가장 간단한 방법은 @Transactional 애너테이션을 트랜잭션이 필요한 영역에 추가해 주는 것이다.

@Service
@Transactional
public class MemberService {
    private final MemberRepository memberRepository;

    public MemberService(MemberRepository memberRepository) {
        this.memberRepository = memberRepository;
    }
    public Member createMember(Member member) {
        verifyExistsEmail(member.getEmail());
        return memberRepository.save(member);
    }
    //메서드 레벨 트랜잭션
    @Transactional(readOnly = true)
    public Member findMember(long memberId) {
        return findVerifiedMember(memberId);
    }
}

메서드 레벨에도 트랜잭션을 추가할 수 있다. 여기서 readOnly 속성을 읽기 전용 트랜잭션으로 적용한 것이다.

트랜잭션 전파

트랜잭션의 경계에서 진행 중인 트랜잭션이 존재할 때 또는 존재하지 않을 때, 어떻게 동작할지 결정하는 방식. 아래와 같은 propagation 유형을 사용할 수 있다.

  1. Propagation.REQUIRED
    propagation 유형의 디폴트 값. 진행중인 트랜잭션이 없으면 새로 시작하고, 있다면 해당 트랜잭션에 참여한다.
  2. Propagation.REQUIRES_NEW
    이미 진행중인 트랜잭션과 무관하게 새로운 트랜잭션이 시작되고, 새로 시작된 트랜잭션이 종료할 때까지 기존 트랜잭션이 중지된다.
  3. Propagation.MANDATORY
    진행중인 트랜잭션이 없으면 예외를 발생시킨다.
  4. Propagation.NOT_SUPPORTED
    트랜잭션이 필요하지 않음을 의미한다. 진행 중인 트랜잭션이 있으면 메서드 실행이 종료될 때 까지 진행중인 트랜잭션은 중지되며, 메서드 실행이 종료되면 트랜잭션을 계속 진행한다.
  5. Propagation.NEVER
    트랜잭션을 필요로 하지 않음을 의미하며, 진행 중인 트랜잭션이 존재할 경우에는 예외를 발생시킨다.

트랜잭션 격리 레벨

트랜잭션은 다른 트랜잭션에 영향을 주지 않고, 독립적으로 실행되어야 격리성이 보장되어야 한다. 이를 isolation 속성을 통해 지정한다.

  1. Isolation.DEFAULT
    데이터베이스에서 제공하는 기본 값이다.
  2. Isolation.READ_UNCOMMITTED
    다른 트랜잭션에서 커밋하지 않은 데이터를 읽는 것을 허용한다.
  3. Isolation.READ_COMMITTED
    다른 트랜잭션에 의해 커밋된 데이터를 읽는 것을 허용한다.
  4. Isolation.REPEATABLE_READ
    트랜잭션 내에서 한 번 조회한 데이터를 반복해서 조회해도 같은 데이터가 조회되도록 한다.
  5. Isolation.SERIALIZABLE
    동일한 데이터에 대해서 동시에 두 개 이상의 트랜잭션이 수행되지 못하도록 한다.
profile
BE 개발자를 꿈꾸는 대학생

0개의 댓글