상세 컨텐츠

본문 제목

Transaction

개인 공부/Database

by 카페코더 2020. 6. 26. 17:24

본문

반응형

Transaction 탄생 배경

데이터베이스의 상태를 변환 시키는 하나의 논리적인 기능의 작업 단위를 말한다. 데이터 베이스를 다루다 보면, 쿼리 한 줄로 해결할 수 없는 경우가 많다. 또, 여러개의 쿼리가 처리되는 상황에서 문제가 생긴다면, 시스템 전체에 큰 문제가 발생한다. 

예시로, 게임 홈페이지에서 캐쉬를 충전한 후, 아이템을 구매하여 먼저 받은 후, 캐쉬가 감소하는 시점에서 서버 전체의 전원이 나간 경우를 생각해보자. 이 상황에서 유저는 아이템을 구매해서 인벤토리에 존재하지만, 잔여 캐쉬는 그대로인 경우가 생길 수 있다. 이것은 게임회사에게 엄청난 비용적 손실을 유발할 것이다.

위와 같은 예시를 방지하기 위해 Transaction 기술이 탄생하였다.


Transaction 개념

DBMS에서 중요한 부분을 담당한다. SELECT, INSERT, UPDATE, DELETE 등의 작업을 하나의 논리적인 작업 단위로 수행하는 일련의 작업을 말한다. 쉽게 말해, 데이터베이스 작업을 위해 수행하는 작업의 단위를 말한다.

작업단위는 많은 질의어 명령문들을 사람이 정하는 기준에 따라 정하는 것을 의미한다.

다음 상황을 생각해보자. "캐쉬로 아이템을 구매하고, 인벤토리에 아이템이 추가된다." 이 상황을 순차적으로 표현해보면, 다음과 같다. 

  1. SELECT - 유저의 캐쉬가 충분한지 검색한다.
  2. INSERT - 유저의 인벤토리에 구매한 아이템을 추가한다.
  3. UPDATE - 유저의 캐쉬를 감소시킨다.(캐쉬의 양을 수정한다.) 

여기서의 작업 단위는 SELECT, INSERT, UPDATE 모두를 합친 것을 말한다.

이러한 작업단위를 하나의 트랜잭션이라 한다.


Transaction의 특징

트랜잭션은 ACID를 보장해야 한다.

  • Atomicity (원자성): 한 트랜잭션 내에서 실행한 작업들은 하나의 작업으로 간주한다. 모두 성공하거나, 모두 실패되어야 한다.
  • Consistency (일관성): 모든 트랜잭션은 일관성있는 데이터베이스 상태를 유지한다. DB에서 정한 무결성 원칙을 항상 만족한다.
  • Isolation (고립성): 동시에 실행되는 트랜잭션들이 서로 영향을 미치지 않도록 격리해야 한다.
  • Durability (영구성): 트랜잭션을 성공적으로 마치면, 그 결과가 항상 저장되어야 한다.

Spring에서 Transaction의 사용법

Spring은 코드 기반의 트랜잭션 및 선언적 트랜잭션을 지원한다.

일반적으로, 서비스 계층(Service Layer)에서 @Transactional을 추가하여 처리한다.

@RequiredArgsConstructor
@Service
public class PostsService {
    private final PostsRepository postsRepository;

    @Transactional
    public Long save(PostsSaveRequestDto requestDto) {
        return postsRepository.save(requestDto.toEntity()).getId();
    }

    @Transactional
    public Long update(Long id, PostsUpdateRequestDto requestDto) {
        Posts posts = postsRepository.findById(id).orElseThrow(() -> new IllegalArgumentException("해당 게시글이 없습니다. id = " + id));

        posts.update(requestDto.getTitle(), requestDto.getContent());

        return id;
    }

    public PostsResponseDto findById (Long id) {
        Posts entity = postsRepository.findById(id).orElseThrow(() -> new IllegalArgumentException("해당 게시글이 없습니다. id = " + id));

        return new PostsResponseDto(entity);
    }

    @Transactional(readOnly = true)
    public List<PostsListResponseDto> findAllDesc() {
        return postsRepository.findAllDesc().stream()
                .map(PostsListResponseDto::new)
                .collect(Collectors.toList());
    }
}
  1. 코드 기반의 트랜잭션 (Programmatic Transaction)

    Spring이 제공하는 트랜잭션 템플릿 및 클래스를 이용한다.
  2. 선언적 트랜잭션 (Declarative Transaction)

    설정파일, 어노테이션을 이용해서 트랜잭션의 범위 및 규칙을 정의하여 사용한다. Spring에서는 주로 선언적 트랜잭션을 이용한다. <tx:advice> 또는 @Transactional 어노테이션을 사용하는데, 쿼리문을 처리하는 과정에서 Exception이 발생시, 자동으로 Rollback 처리를 해준다.

 

반응형

'개인 공부 > Database' 카테고리의 다른 글

DB Isolation Level  (0) 2020.06.26
관계형 데이터 모델링의 흐름  (0) 2020.06.16
데이터베이스 정의  (0) 2020.06.15

관련글 더보기

GitHub 댓글

댓글 영역