TypeOrm/ Transaction

25gStroy·2022년 1월 21일
0

Nest.js

목록 보기
17/23

Transaction

기본적으로 백엔드에서 db관련 로직을 실행해 줄때에는 웬만하면 트렌젝션처리를 해주는것이 기본이다.
예를들어 회원정보를 수정하는 로직이 있다고하고, 해당 작업이 진행중에 어떠한 오류로 인해서 작업이 중단됐을때 Transaction을 걸어줬다면 해당 작업을 하기전으로 데이터가 롤백돼서 데이터가 꼬이거나 유실되는것을 막을 수 있기 때문에 모든 백엔드에서 DB관련 로직을 수행할때는 트렌젝션처리를 잘 해줘야합니다.

ACID

  • Atomicity: transaction의 작업이 부분적으로 성공하는 일이 없도록 보장하는 성질이다. 송금하는 사람의 계좌에서 돈은 빠져나갔는데 받는 사람의 계좌에 돈이 들어오지 않는 일은 없어야 한다.
  • Consistency: transaction이 끝날 때 DB의 여러 제약 조건에 맞는 상태를 보장하는 성질이다. 송금하는 사람의 계좌 잔고가 0보다 작아지면 안 된다.
  • Isolation: transaction이 진행되는 중간 상태의 데이터를 다른 transaction이 볼 수 없도록 보장하는 성질이다. 송금하는 사람의 계좌에서 돈은 빠져나갔는데 받는 사람의 계좌에 돈이 아직 들어가지 않은 DB 상황을 다른 transaction이 읽으면 안 된다.
  • Durability: transaction이 성공했을 경우 해당 결과가 영구적으로 적용됨을 보장하는 성질이다. 한 번 송금이 성공하면 은행 시스템에 장애가 발생하더라도 송금이 성공한 상태로 복구할 수 있어야 한다.

하지만 위 ACID원칙은 완벽하게 지키기 힘들다. 원칙을 완벽하게 지키려면 동시성이 매우 떨어지기때문이다.그래서 타협점을 찾는 과정이 Isolation Level이라고 할 수 있다.

Transaction의 Isolation Level

Isolation level이 낮을수록 문제가 발생할가능성은 커지지만 동시에 더 높은 동시성을 얻을 수 있다.

  • READ UNCOMMITTED
  • READ COMMITTED
  • REPEATABLE READ
  • SERIALIZABLE

REPEATABLE READ

REPEATABLE READ는 반복해서 read operation을 수행하더라도 읽어 들이는 값이 변화하지 않는 정도의 isolation을 보장하는 level이다

READ COMMITTED

READ COMMITTED는 commit 된 데이터만 보이는 수준의 isolation을 보장하는 level이다.REPEATABLE READ transaction이 첫 read operation을 기준으로 consistent read를 수행하는 반면, READ COMMITTED transaction은 read operation 마다 DB snapshot을 다시 뜬다.
“ Commit 된 데이터만 보는 건 당연한 거 아닌가?” 혹은 “아니, SELECT 쿼리마다 snapshot을 다시 뜨면 다음 read에서 복구할 필요가 없는데 snapshot을 왜 뜨는 거야?”라는 생각이 들 수도 있다. 실제 DB에는 아직 commit 되지 않은 쿼리도 적용된 상태다. 따라서 commit 된 데이터만을 읽어오기 위해서는 아직 commit 되지 않은 쿼리를 복구하는 과정이 필요하다. 즉, consistent read를 수행해야 한다.

READ UNCOMMITTED

READ UNCOMMITTED transaction은 기본적으로 READ COMMITTED transaction과 동일하다. 대신, SELECT 쿼리를 실행할 때 아직 commit 되지 않은 데이터를 읽어올 수 있다. 예를 들어, 다음과 같은 상황이 가능하다.

Transaction A에서 row를 삽입했다.
READ UNCOMMITTED transaction B가 해당 row를 읽는다.
Transaction A가 rollback 된다.
이 경우, transaction B는 실제로 DB에 한 번도 commit 되지 않은, 존재하지 않는 데이터를 읽어 들였다. 이러한 현상을 dirty read라고 한다.

SERIALIZABLE

SERIALIZABLE transaction은 기본적으로 REPEATABLE READ와 동일하다. 대신, SELECT 쿼리가 전부 SELECT ... FOR SHARE로 자동으로 변경된다.
SERIALIZABLE isolation level은 데이터를 안전하게 보호할 수는 있지만 굉장히 쉽게 deadlock에 걸릴 수 있다. 따라서 SERIALIZABLE isolation level은 deadlock이 걸리지 않는지 신중하게 계산하고 사용해야 한다.

(출처 : Ditto 님 블로그)

TypeOrm Transaction처리

doc

profile
애기 개발자

0개의 댓글