본문 바로가기
MS-SQL

데이터베이스_특징_트랜젝션_락

by kcj3054 2022. 4. 4.

데이터 베이스 원리

  • 데이터 베이스를 물류 창고에 비유. 3가지 고려해야 할 사항이 존재한다. (하지만 항상 3가지는 상충된다.)
    • 많이 (병렬처리)
    • 빠르게 (응답 속도)
    • 정확하게 (커밋한 데이터를 지킨다)
  • 데이터베이스(물류창고), ------------ 쓰레드(입구지킴이?) ---------클라(고객) 이라고 생각하자.
  • 질문1. 디스크 I/O는 얼마나 느리길래 자꾸 빠르게 빠르게를 말하는가?
    • 서버를 생각해보자 서버에서는 CPU에서 RAM을 왔다갔다하기가 속도 저하가 일어나서 캐쉬(레지스터, L1, L2)를 사용한는데, 여기서 말하는 디스크 IO하드는 RAM보다 더 먼 곳에 위치한다 그래서 DB를 이용할 때도 캐쉬를 사용하는데 여기서 말하는 '캐쉬'는 'RAM'이다.
  • 질문2. 안전하게는 얼마나 안전하게인가?
    • CPU나 메모리가 박살나도 안전해야한다. RAM은 휘발성이라서 데이터가 날아간다, 그래서 데이터를 디스크에 저장해야한다.
  • 질문3 읽고 쓰고 둘다 어떻게 빠르게 하냐?
    • READ는 데이터를 읽어와야하는데 하드까지 가기에 시간이 걸려서 중간에 메모리 캐쉬를 두고 만약 그곳에 데이터가 존재하지 않는다면 하드에서 데이터를 가지고온다. 가지고 올 경우 데이터를 해당 데이터만 가지고 오는 것이 아니라, 주변에 데이터까지 가지고 온다.
    • 참고로 캐시에서 데이터를 정리할 때 보통 LRU(Least Recently Used) 최근에 사용빈도가 적은 것을 정리한다

  • 락? 서버에서 말하는 락인가? 데이터베이스에도 락이 동일하게 존재한다.
  • 서버에서는 READ - LOCK (서로 공유 가능 shared Lock), Write-Lock(서로 상호배타적), 서로 경합이 write가 많이 없을 경우 read - writer lock을 쓰는 것이 더 좋다..
  • DB에서 LOCK을 거는 경우를 생각해보자. DB의 락 종류는 아래와 같다.
    • shared (select)
    • Exclusive (insert, update, delete와 같은 write문..)
    • Update(update는 shared와 Exclusive의 중간이다..)
  • 문제 1. db에서 그럼 lock을 걸때 막 걸면 되지않나 왜 범위를 신경 쓰는가?
    • lock을 거는 범위에 따라서 성능이 좌지우지된다.(Row, page, table, database가 존재)
    • Row락을 거는 것으로 갈 수록 병렬 처리하기가 좋다, 그렇지 자원 소모가 크다 왜 ?
    • 병렬처리가 좋은 이유는 갈 수 있는 범위가 넓기 때문이다, 자원 소모가 큰 이유는 한번 row lock을 걸때 하나씩 거는 것이 아니라, 수천개의 row를 거는데 그럴빠엔 하나의 page에 lock을 거는 것이 자원소모가 덜하다..

트랜젝션

  • 트랜잭션은 원자성이다. ALL OR NOTHING ...이러한 것들을 관리하기 위해서 log를 통해서 관리한다.
  • ex : 로그를 봤는데 A에게서 물건을 없어졌으나, B에게서는 물건은 생기고 골드는 사라졌다 (A와 B가 물건을 거래하는 상황) 이때 A의 로그를 보면서 ROLLBACK을 시켜야한다.
  • begin transaction으로 가다가 중간 부분이 실패한다면 rollback!!! 그렇지만 모두 성공하면 실행으로 옮겨야해서 commit.!!
  • 여러 읽기 / 쓰기를 논리적으로 한번에 묶는다. 트랜잭션 범위는 커넥션 기준이다. 트랜잭션 전파는 여러 메서드 호출이 한 트랜잭션에 묶이도록 하기 위해 필요하다,
  • 트랜잭션과 외부 연동은 주의해야한다. 외부 API호출이 완료된 후 rollback을 하게된다면, api호출은 rolback이 되지않는다.

  • 글로벌 트랜잭션은 두 개 이상의 자원(db, 메시징큐)을 한 트랜잭션으로 처리하는 것이다. 예를 들어 insert와 메시지큐에 데이터를 넣는 것을 하나로 묶을 수 있다. 자원에 대한 처리는 쉽지만, 성능이 안좋다.

트랜젝션 정의

  • 원자성(Atomicity)
    • 트랜젝션의 연산은 데이터베이스에 모두 반영되던지 아니면 전혀 반영되지 않아야한다.
    • 트랜젝션 내 모든 명령이 완벽히 수행되지 않고 어느 하나라도 오류가 발생하면 트랜젝션 전부가 취소되어야한다.
  • 일관성(consistence)
    • 트랜젝션이 실행을 완료하면, 언제나 일관성 있는 데이터베이스 상태로 변화해야한다..
    • 시스템이 가지고 있는 고정 요소는 트랜젝션 수행 전과 수행 후가 동일해야한다..
  • Isolation(독립성, 격리성)
    • 둘 이상의 트랜잭션이 동시에 병행 실행되는 경우 어느 하나의 트랜잭션 실행중에 다른 트랜잭션의 연산이 끼어들 수 없다.
    • 수행중인 트랜젝션은 완전히 완료될때까지 다른 트랜잭션에서 수행결과를 참조할 수 없다.
  • Durablility(영속성, 지속성)
    • 성공적으로 완료된 트랜젝션의 결과는 시스템이 고장나더라도 영구적으로 반영되어야한다.

트랜잭션 격리 수준

  • Read Committed

  • Repeatable Read

  • Serializable

  • 여러 클라이언트 같은 데이터에 접근할 때 문제가 발생하는데 그것을 race condition이라고한다.

  • 순서대로 실행하면 되지만 성능이 저하된다 그래서 다양한 격리 수준을 지원한다.

Read Committed

커밋되지 않은 데이터를 읽기를 dirty read라고한다

  • A라는 사람은 데이터를 insert하고 commit을 하지 않은 상태에서 B라는 사람이 조회를 하면 데이터가 깨지는 현상이 발생한다 dirty read..

  • 위의 그림에서 A가 inser into를 할 때 stock은 2개 이상황에서 commit이 되기전에 B가 데이터를 조회하면 stock이 2개, cnt는 1개가 조회된다 아직 A가 commit을 하지 않아서 이렇게 데이터 깨지게된다..

커밋되지 않은 데이터를 덮어 쓰기 dirty write

  • dirty read, dirty write를 해결하기위해서 read committed로 커밋된 데이터만 읽기, 커밋된 값과 트랜잭션 진행 중인 값을 따로 보관
  • 커밋된 데이터만 덮어쓸 수 있도록한다. , 행 단위 잠금을 사용하여 같은 데이터를 수정한 트랜잭션이 끝날 때까지 대기를한다.

Repeatable Read

  • 트랜잭션이 진행 중인 동안 데이터가 변경되어서 같은 데이터를 읽게한다.(특정 버전에 해당하는 데이터만 읽음)

변경 유실에 대한 몇가지 처리 방법

  • 원자적 연산을 처리하면 동시 수정 요청에 대해 db가 순차 처리를 한다..

  • 명시적으로 잠금

    • 조회할 때 수정할 행을 미리 잠금해서 select조차 못하게 막는다.
  • -CAS

    • 수정할 때 값이 같은지 비교해서 같은 값일 경우에만 수정을한다. 이것을 통해 변경이 유실되는 것을 방지

Serializable

    • 이름 그대로 순차적으로 할 수 있나 그렇게 하면 늦어진다. 그래서 인덱스 잠금이나 조건 기반 잠금을 사용한다.

'MS-SQL' 카테고리의 다른 글

Clustered vs NonClustered  (0) 2022.04.05
복합인덱스  (0) 2022.04.05
패턴매칭_수치연산  (0) 2022.04.05
인덱스 분석  (0) 2022.04.04
MS -SQL?  (0) 2022.04.04