[Dining-together] 트랜잭션(Transaction)과 @Transactional 정리

Jifrozen·2021년 5월 31일
0

Dining-together

목록 보기
7/25

서론

코드 리뷰를 하던 중 팀원이 Transcational 어노테이션을 달아주면 좋겟어요! 다른 답변을 받았다...Transaction? DB 공부할때 들어본것같은데 뭐더라...! 해서 한번 정리하게 됐다.

transaction?

다들 이런 예를 많이 들더라.

  1. a가 b에게 10000원을 송금한다.
  2. 송금 중, 오류가 생겨 a의 계좌에는 10000원이 빠져나갔지만 b의 계좌에는 10000원이 들어오지 않았다.
  3. 이와 같은 상황을 막기위해 거래가 성공적으로 모두 끝나야 이를 완전한 거래로 승인하고, 거래 도중 뭔가 오류가 발생했을 때는 이 거래를 처음부터 없었던 거래로 완전히 되돌리는 것입니다.

트랜잭션(Transaction)은 데이터베이스의 상태를 변환시키는 하나의 논리적 기능을 수행하기 위한 작업의 단위 또는 한꺼번에 모두 수행되어야 할 일련의 연산들을 의미한다.

그러니깐 한마디로 송금하고 b계좌가 그걸 update하는 작업을 하나의 작업으로 생각해 두개의 작업중 하나라도 오류가 생기면 모두 처음의 상태로 돌리는 작업이다.
이러한 트랜잭션을 처리하기 위해 두가지 명령을 사용한다.

  • 커밋(Commit): 모든 부분작업이 정상적으로 완료하면 이 변경사항을 한꺼번에 DB에 반영합니다.
  • 롤백(Rollback): 부분 작업이 실패하면 트랜잭션 실행 전으로 되돌립니다.
    하나의 트랜잭션 처리가 비정상적으로 종료되어 데이터베이스 일관성을 깨뜨렸을 때 트랜잭션의 일부가 정상적으로
    처리되었더라도 트랜잭션의 원자성을 구현하기 위해 이 트랜잭션이 행한 모든 연산을 취소하는 연산입니다.

모든 연산을 처음으로 돌리지 않고 싶을 때 사용하는것이 savepoint이다.

트랜잭션 연산 및 상태

트랜잭션의 특징

ACID(Atomicity, Consistency, Isolation, Durability)
데이터베이스에서 트랜잭션이 안전하게 수행된다는 것을 보장하는 특징이다.

  • 원자성(Atomicity) : 트랜잭션이 DB에 모두 반영되거나, 혹은 전혀 반영되지 않아야 한다.
  • 일관성(Consistency) : 트랜잭션의 작업 처리 결과는 항상 일관성이 있어야 한다.
  • 독립성(Isolation) : 둘 이상의 트랜잭션이 동시에 병행 실행되고 있을 때, 어떤 트랜잭션도 다른 트랜잭션 연산에 끼어들 수 없다.
  • 영속성(Durability) : 트랜잭션이 성공적으로 완료 되었으면 결과는 영구적으로 반영되어야 한다.
    위는 기본적으로 트랜잭션이 지켜야할 특징이다.
  • 성능 보장을 위해 ACID가 완화되는 경우
    100개를 처리할때 독립성으로 순차적으로 처리하는 경우 성능문제가 생긴다. 동시성을 얻기 위한 한가지 방법으로 트랜잭션 격리 설정이 있다.

트랜잭션 격리 수준

  • READ-UNCOMMITTED
    : 거밋 전의 트랜잭션 데이터 변경 내용을 다른 트랜잭션이 읽는 것 허용 -> Dirty read, Non-Repeatable Read, Phantom read

  • READ-COMMITTED
    : 커밋이 완료된 트랜잭션의 변경사항만 다른 트랜잭션에서 조회 가능 -> Non-Repeatable Read, Phantom read
    Non-Repeatable Read -> 데이터 불일치 문제

  • REPEATABLE-READ
    : 트랜잭션 범위 내에서 조회한 내용이 항상 동일함을 보장
    -> phantom Read
    phantom Read -> Non-Repeatable Read의 종류로 데이터 두번 조회했을때 새롭게 생기거나 없어지는 현상

  • SERIALIZABLE
    : 한 트랜잭션에서 사용하는 데이터를 다른 트랜잭션에서 접근 불가

트랜잭션 전파 타입

그래서 @Transactional이 뭔데?

스프링에서도 트랜잭션 처리를 지원하는데(여러 방식이 있다) 그 중 어노테이션 방식으로 @Transactional을 선언하여 사용하는 방법이 일반적이며, 선언적 트랜잭션이라고 부른다.
클래스나 메소드 위해 @Transactional 이 추가되면, 이 클래스에 트랜잭션 기능이 적용된 프록시 객체가 생성된다.
프록시 객체는 @Transactional이 포함된 메소드가 호출 될 경우, PlatformTransactionManager를 사용하여 트랜잭션을 시작하고, 정상 여부에 따라 Commit 또는 Rollback 한다.

@Transcational 옵션

  1. isolation
    트랜잭션에서 일관성없는 데이터 허용 수준을 설정한다
    -> 위에 설명한 4가지 수준

  2. propagation
    트랜잭션 동작 도중 다른 트랜잭션을 호출할 때, 어떻게 할 것인지 지정하는 옵션이다

  3. noRollbackFor
    특정 예외 발생 시 rollback하지 않는다.

  4. rollbackFor
    특정 예외 발생 시 rollback한다.

  5. timeout
    지정한 시간 내에 메소드 수행이 완료되지 않으면 rollback 한다. (-1일 경우 timeout을 사용하지 않는다)

  6. readOnly
    트랜잭션을 읽기 전용으로 설정한다.

2. propagation (전파속성)

  • REQUIRED (Defualt)
    이미 진행중인 트랜잭션이 있다면 해당 트랜잭션 속성을 따르고, 진행중이 아니라면 새로운 트랜잭션을 생성한다.

  • REQUIRES_NEW
    항생 새로운 트랜잭션을 생성한다. 이미 진행중인 트랜잭션이 있다면 잠깐 보류하고 해당 트랜잭션 작업을 먼저 진행한다

  • SUPPORT
    이미 진행 중인 트랜잭션이 있다면 해당 트랜잭션 속성을 따르고, 없다면 트랜잭션을 설정하지 않는다.

  • NOT_SUPPORT
    이미 진행중인 트랜잭션이 있다면 보류하고, 트랜잭션 없이 작업을 수행한다.

  • MANDATORY
    이미 진행중인 트랜잭션이 있어야만, 작업을 수행한다. 없다면 Exception을 발생시킨다.

  • NEVER
    트랜잭션이 진행중이지 않을 때 작업을 수행한다. 트랜잭션이 있다면 Exception을 발생시킨다.

  • NESTED
    진행중인 트랜잭션이 있다면 중첩된 트랜잭션이 실행되며, 존재하지 않으면 REQUIRED와 동일하게 실행된다.

정말 고마운 분들!

https://goddaehee.tistory.com/167 [갓대희의 작은공간]
https://velog.io/@kdhyo/JavaTransactional-Annotation-알고-쓰자-26her30h
https://www.youtube.com/watch?v=e9PC0sroCzc&t=337s
https://coding-factory.tistory.com/226
https://devuna.tistory.com/30 [튜나 개발일기]

0개의 댓글