sparcs-kaist / otlplus-server

OTL Plus의 NestJS 마이그레이션입니다.
https://otl.kaist.ac.kr
5 stars 0 forks source link

Issue/119/transaction #121

Closed LarryKwon closed 1 month ago

LarryKwon commented 2 months ago

2가지 구현을 완료했습니다.

  1. TranManager
  2. CLS Module을 이용한 방식

TranManager는 처음에 Init 될 때 prismaService를 주입받은 후, transaction이라는 함수를 호출할 때마다 주입받은 prismaService에서 transaction을 시작하고 추가적인 로직을 실행하는 식으로 동작합니다.

CLS 방식은 continuation-local-storage의 약자로, 싱글 쓰레드로 동작하는 node.js에서 request 단위로 무언가를 저장하거나 식별하기가 어려운 문제를 해결하는 방식입니다.

두 개 중에서 선호되는 것은 CLS 방식입니다. 이유는 다음과 같은데요.

  1. TranManager에서 transaction propagation(https://mangkyu.tistory.com/269) 과 같은 걸 구현하려고 getTx가 있는데, 이게 새로운 transaction이 실행될 때마다 static property를 갈아끼우는 식으로 구현되어있다보니, 여러 요청이 들어왔을 때, 정상적인 request의 transaction을 물고 갈지 의문입니다. (예를 들어, A를 처리하던 중, B가 시작되고 이 때 A에서 getTx()를 호출하면 다른 transaction을 물고가나?)
  2. prisma에는 같은 틱 상에서 findUnique를 하게 되면 그 두 개는 in으로 묶어서 처리해주는 방식이 있습니다. (https://www.prisma.io/docs/orm/prisma-client/queries/query-optimization-performance). 이 방식으로 테스트 코드를 짜봤는데, TranManager는 트랜잭션으로 격리가 안 된채로 조회가 되더라고요. (10,11) / (12,13) 두 개를 각각 Transaction을 걸고 Promis.all로 같이 날렸더니 쿼리는 (10,12), (11,13)으로 날라감. 반면 이 부분은 CLS는 의도한대로 (10,11) / (12,13) 이렇게 잘 날라감.
  3. 다만 CLS는 지금 설치가... 잘 안 되서 npm install --force를 해야합니다....
LarryKwon commented 2 months ago

node.js 기반 프레임워크에서 여러 request 처리할 때, 어떻게 동작하는지, static property 건드리면 어떻게 될지 얘기해보면 좋을 것 같아용