실전 프로젝트 12일차 회고

SaGo_MunGcci·2022년 9월 7일
0

실전 프로젝트

목록 보기
9/19

Today do list

  • Transaction

  • isolation level

  • 태그 기능 추가 및 해당 단어가 들어간 경매 게시글 검색.



TIL

  • WebSocket을 이용한 실시간 채팅을 구현하고 실시간으로 테이블을 조작하는 부분(호가 및 채팅 기록 저장)이 있어서 사용자 별로 정확한 데이터를 Response해 주고 싶었다.

  • PM님께서 동시성 및 isolation level과 관련해서 테이블을 다루는 Transaction을 공부해보는 것이 좋을 것 같다는 말씀을 듣고 이렇게 정리 한다.

Transaction

  • 정의 : 하나의 논리적 기능을 정상적으로 수행하기 위한 작업의 기본 단위, 한꺼번에 모두 수행되어야 할 일련의 연산이다.

--> 트랜잭션은 사용자로 하여금 자신이 정확한 데이터를 입출력 할 수 있다는 확신을 주게 하는 중요한 부분이다.

  • 쿼리를 하나로 처리해서 만약 중간에 실행이 중단됐을 경우, 최종 커밋 시점으로 되돌리는 Rollback 을 수행하고, 오류없이 마치면 Commit 을 실행하는 단위이다.

    • 커밋(COMMIT) : 트랜잭션을 메모리에 영구적으로 저장

    • 롤백(ROLLBACK) : 오류가 발생했을 때, 오류 이전의 특정 시점 상태로 되돌려주는 제어어

    • 체크포인트(CHECKPOINT) : 롤백을 위한 시점을 지정

트랜잭션 특성!

⦁ 원자성(Atomicity) : 분해가 불가능한 작업의 최소단위, 연산 전체가 Commit 또는 Rollback이 반드시 되어야 한다.

⦁ 일관성(Consistency) : 트랜잭션이 실행 성공 후 항상 일관된 데이터베이스 상태를 보존해야 한다.

  • 트랜잭션이 성공적으로 수행된 후에도 데이터베이스가 일관성 있는 상태를 유지해야 한다. 여기서 말하는 일관성이란, 크게 2가지 의미를 가진다.

  • 첫 번째로, 트랜잭션이 커밋되면 데이터 베이스에 적용한 제약조건(PRIMARY KEY, UNIQUE, NOT NULL 등)을 위반하지 않는다는 보장을 의미한다.

    → 예시) 사용자가 번호를 저장하려고 하는데, 이 번호에 UNIQUE 제약이 설정되어 있으면 중복되니 사용자 번호를 저장할 수 없어야 한다.

  • 두 번째로, 트랜잭션의 작업이 애플리케이션에서 의도하고자 한 작동이 정상적으로 일어난다는 보장을 의미한다.

    → 재고가 떨어졌을 때, 더 이상 판매를 할 수 없도록 제한해야 한다.

⦁ 격리성(Isolation) : 트랜잭션 실행 중 연산의 중간 결과를 다른 트랜잭션이 접근할 수 없어야 한다.
→ 아래에 후술 함.

⦁ 영속성(Durability) : 성공 완료(Commit)된 트랜잭션의 결과는 영속적으로 데이터베이스에 저장되어야 된다.

병행제어(Concurrency Control) - 일관성 주요 기법

다수 사용자 환경에서 여러 트랜잭션을 수행할 때, 데이터베이스의 일관성 유지를 위해 상호작용을 제어하는 기법

병행제어 기법 종류

⦁ 로킹(Locking) : 일관성과 무결성을 유지하기 위한 트랜잭션의 순차적 진행을 보장하는 직렬화 기법

⦁ 낙관적 검증 : 일단 트랜잭션을 수행하고, 트랜잭션 종료 시 검증을 수행

⦁ 타임 스탬프 순서 : 타임 스탬프를 부여해 부여된 시간에 따라 트랜잭션 수행

⦁ 다중버전 동시성 제어(MVCC) : 타임스탬프를 비교해 직렬가능성이 보장되는 적절한 버전을 선택해 접근하도록 함

  • 일단은 이런 것들이 있다는 것만 알고 넘어감.

Isolation Level

왜 격리 수준이 있는가?

참고 : https://jaeseongdev.github.io/development/2021/06/16/%ED%8A%B8%EB%9E%9C%EC%9E%AD%EC%85%98%EC%9D%98-%ED%8A%B9%EC%A7%95-%28ACID%29/

⦁ 트랜잭션을 수행 시 다른 트랜잭션의 연산 작업이 끼어들지 못하도록 보장하는 것을 의미한다.

⦁ 예를 들면, 부산의 지정 호텔에 남은 싱글룸 수가 10개였을 때 실제로 숙박하는 로직은 다음과 같다.

  1. 현재 빈 싱글룸의 수를 확인한다(SELECT)

  2. 빈 싱글룸 수에서 1을 빼고 결과를 빈 싱글룸 수로 되돌려 쓴다(UPDATE)

  3. 이것을 사용자 A와 사용자 B가 동시에 수행하면 어떻게 될까? 2명이 방을 확보한다면 원래 빈 싱글룸 수는 2개가 줄어야 하지만, 같은 방을 동시에 확보하게 되면 빈 싱글룸 수는 1개만 줄어들게 된다.

⦁ 이런 사태가 발생하는 것을 막기 위해, 데이터베이스에는 테이블에 대해 Lock(잠금)을 걸어서 후속처리를 Block하는 방법이 있다.

⦁ 잠금 단위에는 테이블 전체, 블록, 행 등이 있는데, MySQL에서는 트랜잭션 처리를 할 때 주로 행 단위의 잠금 기능을 이용한다.

⦁ 예를 들어, 앞의 두 가지 중 ‘1. 현재 빈 싱글룸 수를 확인한다’를 처리할 때 ‘SELECT ~ FOR UPDATE’를 실행하면 SELECT한 행에 잠금이 걸린다.

⦁ 이렇게 되면 후속 처리는 해당 잠금이 해제될 때(COMMIT 또는 ROLLBACK)까지 대기하게 되며 올바른 처리를 계속할 수 있게 된다.

Isolation Level 종류

DEFAULT

사용하는 DB의 디폴트 격리 단계를 따른다. mysql의 경우REPEATABLE_READ이다.

READ_UNCOMMITTED(Level 0)

가장 낮은 단계로 트랜젝션에 처리중이거나, 아직 commit 되지 않은 데이터를 다른 트랜젝션이 읽는 것을 허용한다. 데이터베이스의 일관성을 유지할 수 없기 때문에 Dirty Read가 발생한다.

Dirty Read

UPDATE, INSERT 반영 전에 데이터를 읽어 생기는 오류이다.

⦁ 트랜잭션 1이 시작한다.

⦁ 트랜잭션 2가 시작한다.

⦁ 트랜잭션 1이 데이터를 수정 후 UPDATE 혹은 INSERT를 진행한다.

⦁ 트랜잭션 2가 UPDATE 혹은 INSERT 된 데이터를 읽는다.

⦁ 트랜잭션 1에 문제가 생겨 롤백을 진행한다.

⦁ 그러나 트랜잭션 2는 여전히 UPDATE 혹은 INSERT 가 된 상태의 데이터를 인식하고 있다.

READ_COMMITTED(Level 1)

⦁ Dirty Read 현상을 방지할 수 있다.

⦁ 트랜젝션이 수행되는 동안 다른 트랜젝션은 접근할 수 없고 대기 상태가 된다.

⦁ commit 된 트랜잭션에 대해서만 조회가 가능하다.

⦁ Non-Repeatable Read가 발생한다.

Non-Repeatable Read

⦁하나의 트랜잭션이 같은 값을 조회할 때 다른 값이 조회되는 현상이다. 커밋된 데이터만 읽어오기 때문에 발생하는 현상이다.

⦁ 트랜잭션 1이 시작한다.

⦁ 트랜잭션 1이 Id=1인 데이터의 값을 A에서 B로 변경한다.

⦁ 트랜잭션 2가 시작한다.

⦁ 트랜잭션 2가 Id=1인 데이터를 조회하면A로 조회된다.

⦁ 트랜잭션 1이 커밋하고 종료한다.

⦁ 트랜잭션 2가 Id=1인 데이터를 다시 조회하면 B로 조회된다.

REPEATABLE_READ(Level 2)

⦁ 트랜잭션 내에서 한번 조회한 데이터를 반복해서 조회해도 같은 데이터가 조회횐다. 즉 조회한 데이터 내용의 동일함을 보장한다.

⦁ 다른 사용자는 트랜잭션 영역에 해당되는 데이터에 대한 수정이 불가능하다.

⦁ 처음 트랜잭션이 시작되면 처음의 데이터에 대해 스냅샷을 남기고, 이후에 값을 변경 후 조회해도 처음에 남긴 스냅샷에서 데이터를 가져와 데이터의 동일함을 보장해준다.

⦁ 레벨 2의 격리 단계에서는 UPDATE한 데이터에 관해서는 정합성을 보장하지만, INSERT/DELETE에 대해서는 보장하지 않는다. 때문에 Phantom Read 문제가 발생한다.

Phantom Read

⦁ 이름처럼 있던 데이터가 사라지거나 없던 데이터가 생기는 현상을 뜻한다.

⦁ 트랜잭션 1이 시작한다.

⦁ 트랙잰셕 1이 Id=1(value = A)인 값을 조회한다.

⦁ 트랜잭션 2가 시작한다.

⦁ 트랜잭션 2가 Id=1인 데이터를 B로 변경한다.(UPDATE)

⦁ 트랜잭션 1이 Id=1인 데이터를 조회하지만 데이터는 여전히 A로 나온다.

⦁ 트랜잭션 2가 Id=2(value = C)인 데이터를 삽입한다.(INSERT)

⦁ 트랜잭션 2가 커밋 후 종료한다.

⦁ 트랜잭션 1이 Id=2인 데이터를 조회하면 C를 확인할 수 있다.

SERIALIZABLE(Level 3)

⦁ 가장 강력한 격리 수준으로 데이터의 일관성을 완벽하게 보장한다.

⦁ 그만큼 동시 처리 성능이 가장 떨어진다.

⦁ 위에서 발생한 현상들은 하나도 발생하지 않는다.

⦁ 트랜잭션이 특정 테이블을 읽으면 다른 트랜잭션은 그 테이블의 데이터를 변경, 수정할 수 없다.

정리

⦁ isolation level이 올라갈 수록 정확성과 신뢰성이 상승하나, 처리 속도가 낮아진다.

⦁ 우리가 구현할 목적에 맞게 isolation level에 따른 트랜잭션 처리를 해주자.

해당 단어가 들어간 경매 게시글 검색



Retrospection

  • DB와 관련해서 트랜잭션이 굉장히 중요하다는 사실을 알게되었다.

  • jpa 쿼리메서드가 생각보다 잘되어있다는 것을 알게되었다.



Tommorrow do list

  • 채팅계속 구현하기


profile
이리저리 생각만 많은 사고뭉치입니다.

0개의 댓글