3 분 소요

CS 퀴즈 (8)

트랜잭션이란 (Transaction)

데이터베이스의 상태를 변화시키기 위해 수행하는 작업단위

  • 원자성(Atomicity)
    • 절반만 되고 그런거 없음
    • All or Nothing, 모든 작업이 실행되거나 혹은 모두 실행되지 않아야 한다.
    • A 계좌에서 B 계좌로 전액을 송금할 때
      • A 계좌 잔액 줄리기 작업과 B 계좌 잔액 늘리기 작업은 함께 성공하거나 함께 실패해야 한다.
  • 일관성(Consistency)
    • 작업처리 결과는 항상 일관적이여야한다.
    • 작업처리 결과는 항상 일관성이 있어야한다.
    • 과거에 어떤 작업을 했을 때 A라는 결과가 나왔다면
    • 그 다음에 동일한 작업을 할 때에 무조건 A가 나와야 한다.
    • 모든 트랜잭션이 종료된 후에는 DB의 제약 조건을 모두 지키고 있는 상태가 되어야 한다.
    • 잔액은 0원 이상이다. -> 이를 위반하는 트랜잭션은 모두 중단된다.
  • 독립성(Isolation)
    • 여러 개의 트랜잭션이 이루어질 때 각 트랜잭션은 독립적으로 한 개씩 수행되어야 한다.
    • A 트랜잭션이 하는 일을 B 트랜잭션은 모들게 해야한다.
    • 성능 관계에 있어서 READ_UNCOMMITTED > READ_COMMITTED > REPEATABLE_READ > SERIALIZABLE 순서로 성능은 떨어지고 격리성은 증가한다.
      • 격리성이 낮을 때는 Drity read, Phantom read 등이 발생한 다.
      • 일반적으로 MYSQL InnoDB의 기본 값인 REPEATBLE_READ 를 많이 활용한다.
  • 지속성(Durability)
    • 트렌젝션이 성공했을 경우 그 결과 값은 영구적으로 지속되어야 한다.
    • commit을 하게 되면 지속(저장)이 꼭 된다.
    • DB 저장이 실패하더라도 모든 로그를 모두 남겨서 DB에 순차적으로 모두 반영되도록 한다.

주로 DB에 문제가 생겼을 때 롤백 시키기 위해 사용된다.

  • 트랜잭션 연산 - 원자성 문제
    • 커밋(Commit) - 트랜잭션이 전체가 성공적으로 이루어졌을 때 마무리 작업으로 커밋 -> 모든 수정사항 반영
    • 롤백(Rollback) - 트랜잭션이 이루어질 때 어떠한 예외상황이 발생 했을 시 전체를 처음으로 되돌림
      • 예를 들어 5단계가 있을 때 중간에 4개가 성공해도 1개가 실패한다면 전부 취소시킴

여러 트랜잭션이 경쟁하면 생기는 문제

Dirty Read

  • 트랜잭션 A : 테이블의 3번째 row 수정중 (커밋전)
  • 트랜잭션 B : 테이블의 3번째 row 조회시도

3번째 row가 2로 수정중이였는데 이 때 B가 조회하면 2로 데이터를 읽어감 하지만 이 때 트랜잭션 실패로 롤백이 되서 기존 데이터가 1로 다시 바뀐다면 B는 잘못된 값을 읽어가게됨(접근이 가능했기 때문에 문제가됨 -> 읽지 못 하게 보호해야함)


Non-Repeatable Read -일관성 문제

  • 트랜잭션 A : 테이블 3번째 row 조회 x 2
  • 트랜잭션 B : 테이블 3번째 row 수정 후 커밋

A가 조회했을 때 아직 트랜잭션이 끝나지 않았지만 B가 껴들어서 수정후 커밋해버리면 A가 첫 번째 조회했을 때와 두 번째 조회했을 때의 값이 달라짐

Phantom Read

  • 트랜잭션 A : 테이블 0~4번째 row 조회 x 2
  • 트랜잭션 B : 테이블 3번째 row 수정 후 커밋

Non-Repeatable Read 은 특정 값을 두 트랜잭션이 경쟁했을 때 생기는 문제
Phantom Read 는 특정 범위 내에서 값을 경쟁했을 때 생기는 문제

Spring 에서 트랜잭션을 어떻게 적용할까?

@Transactional

가장 간단하고 널리 사용함 -> 선언적 트랜잭션
클래스나 매서드 위에 달림 -> 프록시 객체가 생김
(PlatformTransaction Manager) -> 트랜잭션을 관리해줌

Spring 트랜잭션의 세부 설정들

  • Isolation (격리수준)
  • Propagation (전파수준)
  • ReadOnly 속성
  • 트랜잭션 롤백 예외
  • timeout 속성

Isolation (격리수준)

@Transactional(isolation = Isolation.Default)

트랜잭션에서 일관성이 없는 데이터를 허용하는 수준

  • DEFAULT
  • READ_UNCOMMITTED (Dirty Read 발생) (헐겁)
  • READ_COMMITTED (Dirty Read 방지) (트랜잭션 와중에는 아무도 못 읽음 커밋이 되야만 접근 가능)
  • REPEATABLE_READ (Non-Repeatable Read 방지) (보통 무난하게 많이 씀) (트랜잭션 전체가 완료될 때까지 셀렉트 된 부분에 락을 걸어서 격리 -> 다른 사용자는 조회,접근 조차 안됨)
  • SERIALIZABLE (Phantom Read 방지) (일관성 빡빡) -> 성능저하 발생

Propagation (전파수준)

트랜잭션 동작 도중 다른 트랜잭션을 호출하는 상황
트랜잭션을 시작하거나 기존 트랜잭션에 참여하는 방법에 대해 결정하는 속성 값

  • REQUIRED -> 디폴트
    • 부모트랜잭션 A, 자식트랜잭션 B -> A가 B를 호출 했을 떄 부모 트랜잭션안에서 함수 B도 함께 진행
    • 만약 A는 트랜잭션이 없고 B만 있을 경우 B를 위한 새로운 트랜잭션을 만든다.
  • SUPPORTS -> 이미 시작한 트랜잭션이 있으면 참여하고 없으면 트랜잭션 없이 진행
  • REQUIRES_NEW -> 부모A 자식B 이렇게 둘 다 트랜잭션이 있을 경우 부모A 트랜잭션따로 자식 B따로 트랜잭션을 만들어 동작한다..
  • NESTED -> 이미 트랜잭션이 있는 경우에 중첩해서 진행 -> 트랜잭션 안에서 새로운 트랜잭션이 진행
    • -> 부모트랜잭션이 커밋되는지에 대해서 영향을 받지만 자식 트랜잭션의 롤백여부는 부모트랜잭션에 영향을 미치지 않음
    • 부모가 롤백이되면 자식도 롤백 하지만 부모는 롤백되지 않은 상태에서 자식이 롤백될 경우 부모는 커밋되고 자식은 그대로 롤백이됨
      • 예를 들어 로그작성과 일기작성이 이루어질 때 로그작성이 실패하더라도 데이터 작성은 진행되어야 하는 경우 -> 반대로 데이터를 작성이 실패했을 경우 로그도 롤백 되어야함
  • ….. 그 외 더 있음…

ReadOnly 속성

트랜잭션을 읽기 전용 속성으로 지정 @Transactional(readOnly = true)

트랜잭션 성능 최적화 및 특정 트랜잭션안에서 의도적으로 사용 가능


트랜잭션 롤백 예외

예외 발생시 트랜잭션 롤백시킬 경우를 설정

Transactional(rollbackFor = Exception.class) Transactional(noRollbackFor = Exception.class)

Default : RuntimeException, Error 특정 예외에는 롤백 시키고 싶지 않을 경우 사용


timeout 속성

일정 시간 내에 트랜잭션을 끝내지 못 할 경우 롤백

@Transactional(timeout=10)

데이터베이스에 문제가 생겨 오래 걸릴 경우

태그: ,

카테고리:

업데이트:

댓글남기기