백엔드쪽 작은단위 도메인 서비스와 컨트롤러들은 완성했고, 초반엔 익숙치않고 알아야하는 개념들이 있어 진도가 많이못나갔지만 익숙해지니 간단한 컨트롤러나 도메인은 2-3개씩 금방금방 적용한거같다.
검색CRUD, 검색히스토리, 소셜로그인(카카오), 일반로그인, spring security Authenciation filter, 관심종목CRUD, 실시간 종목 주가시세 웹소켓 및 단일 http, 과거 주가시세, 일부 도메인 통합테스트 진행한상태
이제 마지막 피날레 메인 도메인이될 매수,매도 프로세싱을 진행하기전 프로세싱 고민과 진행 후에는 이 예측이 어떻게 달라질지 TIL방식으로 간단히 적어볼려고한다. 매수매도를 진행하기위해선 계좌, 계좌내역, 주문, 주문히스토리 등이 한번에 이루워 져야하기때문에 복잡하고 설계와 플로우 로직을 고민을 많이해야한다. DB 스키마 작업시 서로 연동되는 부분들을 잘해놔야한다. 일단은 FK 개념으로 연결짓고 트랜잭션의 경우는 JPA를 통해 진행할려고한다.
DB설계 고민
지금 상태론 일단 Account, AccountHistory, User DB에 대한 스키마를 작성하고 서로 연관되도록 해논상태다. 먼저 Account 테이블의 경우 신규 유저가 생성된다면 무조건적으로 OneToOne으로 계좌를 가지고있도록하기위해서 JPA Entity를 이용하여 영속성전이 cascade를 통해 부모생성시 자식도 자동으로 생성되도록해놓았다. accountHistory의 경우는 account와 fk로 연관지었지만 없을수도있기때문에 Zero or Many로 적용해놓았다. 나머지 적용하지못한 Order, OrderHistory, TransactionHistory가 있는데 Transaction 부분과 Order부분의 경계를 어떻게 나눠야할지가 고민이다.
트랜잭션고민
db에 데이터를 업데이트할때 transaction을 통해 한번에 이뤄져야하는 부분들이있다.
가상주식의 경우는 매수 주문 요청-> 주문처리시 :계좌 변동, 주문 상태변경(PROCESSING)-> 매수 완료시: 주식 보유량 변경, 주문상태(COMPLETED)변경, 주문내역에 COMPLETED기록 , 매수실패시 :주문 상태 변경(FAILED), 주문내역에 FAILED기록, 차감된 금액 rollback 이런식으로 된다. 정합성을 위해선 모든 과정을한 한번의 트랜잭션 내에서 이루워져야하는데 한가지 예외가 있어 고민되는 부분이 매수매도할때 바로사는게 아닌 PENDING을하는경우이다. PENDING을하다가 일정시간이 지나면 주식에서는 주문실패라 주문취소로 남게된다. 결국 트랜잭션의 핵심 개념과 원칙인 ACID에 대해서 좀더 공부하고 탐구해보자
하지만 rollback을 시킨다면 모든 트래잭션이 원복이되니 돈뿐만아니라 order에 대한 히스토리나 요청도 이전으로 돌아가기때문이다. PENDING이아닌 비즈니스적 오류로인한경우는 주문요청때부터 체결전까지 프로세싱을 예기치않은 오류(critical error) 모두 rollback해야하지만, 이경우는 다르다.
예를들어 내가사고자하는 금액은 300원이고 현재 주식시세가 310원이라면 주문요청은 들어가지만 나머지 진행상태는 대기(PENDING)되다가 진행되어 체결되어야한다.
트랜잭션이 하나라면 아무것도 진행하지못하기때문에 lock이 걸릴수도있다. 또한 대기라는 상태가없다고하더래도 주문요청 트랜잭션과 주문체결 트랜잭션을 별개로 가져가야 한다. 따라서 트랜잭션을 1개로 두는게 아니라 2개로 분리해야한다. 그리고 체결이 이루워지지않았다면 체결 트랜잭션은 롤백시키고(계좌 금액), 주문요청은 CANCELLED 로 업데이트해야한다. 이때역시 주기적인 주가 체크(배치 Job schedule)를 하여 살수있는 시세가 되었는지 할지 실시간 웹소켓으로 체크할지도 정해야한다.
한가지 아마 컨트롤이 불가능한 에러도있을것이다. 한국투자 API를 사용하는데 초당 제한 요청건이 정해져있고 이를 넘으면 에러처리가된다. 보통 API를 개인적으로 사용하여 주식을 매수매도하는 한명이라면 상관없지만 이를 이용해서 서비스하는 입장에선 5명의 유저만이라도 동시에 매수/매도 요청을한다면 1초당 5번의 요청이라 몇명은 적절한 요청이더래도 실패할경우다. 이경우 다른 API사용시처럼 어쩔수없이 synchroized 동기화식에 sleep 500(0.5초)를 둬야한다. 만약 100명의 유저가 동시에 요청한다면 마지막사람은 50초후에 진행되더라도 컨트롤불가능한 상황에서 에러보단 처리를 하게 만들어줘야하기떄문이다.
아마 이거를 집중해서한다면 빠르면 1주일, 늦으면 2주일정도 걸릴거같다. 아 추가로 내역도봐야하고 계좌도봐야하니 부부부분 컨트롤러까지 완성하면 3주정도걸릴거같다. 목표는 3월안에 끝내기. 이부분을 끝내고나면 JPA, DB에대한 강의와 책을 통해 좀더 보완하고 이를통해 과부화테스트(JMeter같은걸로 )를 진행하여 트랜잭션이나 일반 DB 사용 최적화를 진행해볼려고한다. 그리고 기본 자바사용법이나 OOP관련해서 한번더 짚고 갈려고한다.
이렇게 되면 백엔드 과정은 모두 끝낼예정이다.
'TIL' 카테고리의 다른 글
AWS IPv4 프리티어제외 유료화 (1) | 2025.02.02 |
---|---|
Graphql 데이터 최적화 (0) | 2023.09.14 |
[TIL] iframe, GraphQL, git 전략 rebase (0) | 2023.05.05 |
[TIL] 도서추가, 마이크로프론트엔드, 소프트웨어 공학 (2) | 2023.03.30 |
[TIL] 짧은 회고록 및 계획, 앞으로 읽을 책들 (0) | 2023.03.15 |