DB는 중복키 이슈를 어떻게 방지하는가? - 트랜잭션

장범준·2023년 2월 4일
0

데이터베이스

목록 보기
1/1

출처 : https://velog.io/@wisepine/MySQL은-따닥을-어떻게-방어할까

mysql은 정확한 시간에 동시에 요청하더라도 동일 키로 삽입되는 것은 불가능하다고 한다. 여기서 키는, 내가 postgresql에서 항상 index로 사용하던, auto-incremeneted인 Primary key라고 생각하면 된다고 한다.

MySQL은 내부적으로 동시 insert 요청을 어떻게 처리하느냐에 대해, 세가지 기술이 있다는 답변이 왔다.

트랜잭션 스케줄러

대기중인 트랜잭션간 우선순위를 매기는 스케줄러를 사용하고 있다고 한다.
그런데 여기서 트랜잭션이 뭘까?

트랜잭션

트랜잭션은 데이터베이스의 상태를 변환시키기 위해 수행하는 작업단위이다.

여기서 상태를 변화시킨다는 것은, 내가 그동한 쓰던 SELECT, INSERT, DELETE, UPDATE 등의 쿼리문으로 DB에 접근하는 것이라고 한다.

그런데 SELECT는 DB 내용을 참조만 하고, 정보는 조작하지 않을 수도 있지 않나? 이런 경우에도 데이터베이스의 상태를 변환시켰다고 하는가? 트랜잭션의 성질에 대해 알아보며 생각해보자.

또, 여기서 작업 단위란 여러가지 SQL 명령문들을, 기준에 따라 묶은 것이라고 생각하면 되는 것 같다.


예시) 사용자 A가 사용자 B에게 만원을 송금한다.

  • 이때 DB 작업
    1. 사용자 A의 계좌에서 만원을 차감한다 : UPDATE 문을 사용해 사용자 A의 잔고를 변경
    1. 사용자 B의 계좌에 만원을 추가한다 : UPDATE 문을 사용해 사용자 B의 잔고를 변경

현재 작업 단위 : 출금 UPDATE문 + 입금 UPDATE문
→ 이를 통틀어 하나의 트랜잭션이라고 한다.

  • 위 두 쿼리문 모두 성공적으로 완료되어야만 "하나의 작업(트랜잭션)"이 완료되는 것이다. Commit
  • 작업 단위에 속하는 쿼리 중 하나라도 실패하면 모든 쿼리문을 취소하고 이전 상태로 돌려놓아야한다. Rollback

출처 : https://gyoogle.dev/blog/computer-science/data-base/Transaction.html


원자성

트랜잭션의 연산은 데이터베이스에 모두 반영되거나, 혹은 전혀 반영되지 않아야 한다.
'작업단위'라는 표현이 이런 의미였구나. 작업 단위 내에 여러가지 쿼리문이 들어갈 수 있지만, 이들은 모두 하나의 작업으로 작동해야 한다는 뜻인 것 같다.

즉, 트랜잭션 내의 명령 중 어느 하나라도 오류가 발생하면 트랜잭션 전부가 취소되어야 할 것이다.

일관성

트랜잭션이 실행을 성공적으로 완료하면, 언제나 일관성 있는 데이터베이스 상태로 변환된다.

시스템이 가지고 있는 고정 요소는 트랜잭션 수행 전과 트랜잭션 수행 완료 후의 상태가 같아야 한다.

무슨 말인지 잘 모르겠다.

독립성

둘 이상의 트랜잭션이 동시에 병행 실행되는 경우, 어느 하나의 트랜잭션 실행 중에 다른 트랜잭션의 연산이 끼어들 수 없다.

수행중인 트랜잭션은 완전히 완료될 때까지 다른 트랜잭션에서 수행 결과를 참조할 수 없다.

'작업단위'의 다른 의미라고 생각하면 될 것 같다.

영속성, 지속성

성공적으로 완료된 트랜잭션의 결과는 시스템이 고장나더라도 영구적으로 반영되어야 한다.

마찬가지로 무슨 말인지 잘 모르겠다.

또, 트랜잭션이 성공적으로 끝났고, DB가 일관성 있는 상태일 때 이를 알려주기 위해 Commit이라는 연산을 사용하며,

하나의 트랜잭션 처리가 비정상적으로 종료되어 트랜잭션 원자성이 깨진 경우, 트랜잭션의 시작 상태로 roll back 할 수 있다고 한다.

기억해두자.

스케줄러

공식 문서에 따르면 MySQL은 이제 CATS(Contention-Aware Transaction Scheduling) 알고리즘을 쓰고 있다고 한다.

예전엔 FIFO(First-In-First-Out) 알고리즘을 기본으로, CATS를 병용했다고 한다.
CATS는 처음인데, FIFO는 자료구조 공부 때 들어서 조금 익숙한 것 같다.

CATS algorithm is based on : not all transactions are equal, and not all objects are equal

모든 트랜잭션과 모든 객체가 동일하지는 않으니, 우선순위를 두고자 함인 것 같다.

여기서 우선순위는, 간단히 말해 가장 여러개의 트랜잭션과 종속되어 있는 트랜잭션을 먼저 처리한다는 것이다.

이렇게 하면 한번에 더 많은 트랜잭션을 처리하는 경향이 생기고, 속도가 빨라진다.

이후 내용은 추후 업데이트 할지도 모르겠다.

profile
안녕하세요!

0개의 댓글