Skip to content

Feature/zzambas step4#35

Merged
ZZAMBAs merged 59 commits intobase/zzambasfrom
feature/zzambas_step4
Feb 23, 2025
Merged

Feature/zzambas step4#35
ZZAMBAs merged 59 commits intobase/zzambasfrom
feature/zzambas_step4

Conversation

@ZZAMBAs
Copy link

@ZZAMBAs ZZAMBAs commented Feb 23, 2025

내부적 변화

  • User에 송금 설정을 결정하는 SendingType enum을 추가했습니다. EAGER는 기존 즉시 송금이고 LAZY는 수금자가 직접 수금해야 하는 설정입니다.
  • 거래 내역을 관리하는 transaction 테이블을 추가했습니다. 기본적으로 송금 계좌, 수금 계좌, 금액, 상태를 가집니다. 상태는 PENDING, FINISHED, CANCELLED가 존재하며 각각 송금 처리, 수금 완료, 취소됨을 나타냅니다.

구현사항

  • 송금 사용자의 설정에 따라 바로 송금이 이뤄지지 않을수도 있음
    • User 엔티티에 sendingType으로 필드를 추가했고, 이 값에 따라 즉시 송금인지, 지연 송금인지 결정됩니다. TransactionProcessor.wireTransfer()에서 해당 필드 값에 따라 다른 전략이 선택되어 실행됩니다.
  • 금액을 받는 사용자가 직접 확인 후 금액을 받아야 함
    • TransactionProcessor.receive()로 구현되어 있습니다. PENDING 상태인 거래를 FINISHED로 업데이트 처리하고 이 업데이트가 정상 실행되었으면 계좌에 금액을 추가합니다.
  • PENDING 상태일 때 송금자 계좌에서는 금액이 빠져나가 있어야 함
    • 트랜잭션 내에서 거래 내역을 테이블에 저장한 후, 송금자 계좌에서 금액을 업데이트 처리합니다.
  • Pending 상태의 잔액은 송금을 취소할 경우, 원래 금액으로 수령
    • 그 거래 상태를 CANCELLED로 바꾸고 송금자 금액을 업데이트 합니다.
  • Pending 상태로 머물러 있는 최대 기한은 72시간이며, 24시간이 남았을 시 금액을 받는 사용자에게 Remind 알림이 발송
    • 스케줄링을 이용해 처리 중입니다. 현재는 5분 단위로 알림을 보낼 거래 내역들을 검색하고 전송합니다.
    • 동일 거래 내역에 대한 중복 메일 발송을 방지하기 위해 커서를 따로 저장하고 있습니다. 이 커서는 마지막으로 보낸 메일의 id 값과 데드라인을 가지고 있습니다.
    • 72시간이 지난 PENDING은 자동 취소 처리를 해야 하는데, 그 데드라인을 딱 맞출 필요는 없다고 생각하고 매 1분마다 스케줄링으로 취소하도록 했습니다. 여기서 쿼리 횟수를 줄이기 위해 임시 테이블을 생성해 롤백할 금액을 벌크 삽입하고 그 임시 테이블과 계좌 테이블을 조인하여 벌크 업데이트 하도록 했습니다.

프로그래밍 요구사항

  • Pending 상태의 금액이 절대 유실되어선 안 됩니다. 데이터를 어떤 방식으로 저장해야 할지에 대해서도 매우 깊은 고찰이 필요합니다.
    • 현재는 따로 테이블에 저장하고 있으며 DB에 저장되므로 유실이 일어날 수 없다고 생각합니다. (DB 서버가 문제가 생길 수 있다면 클러스터링을 이용해야 하지 않을까... 생각만 하고 있습니다)
  • 해당 구조 변경이 기존 송금 트랜잭션 구조에 어떠한 영향을 미치나요? 여전히 동시성 문제에서 자유로워야 합니다.
    • 기존 송금 트랜잭션 구조에는 영향을 미치지 않았으며, 동시성 문제는 락으로 인해 해결되고 있다고 생각합니다.
  • 상당한 대량 처리가 필요한 쿼리가 많습니다. 쿼리 성능을 따져가며 기능 구현을 진행해야 합니다.
    • 쿼리 성능에 중요한 것으로 저는 쿼리 횟수, 쿼리 한 번의 실행 시간 최소화, 병렬 처리로 보고 있습니다. step 4에서 대량 처리는 메일 연산, 자동 송금 취소 연산으로 보았고, 메일은 병렬 처리로 수행 시간을 줄이려고 했고, 자동 송금 취소는 쿼리 횟수 최소화로 수행 시간을 줄이려고 했습니다.

기타

Transaction 관련 클래스들과 Mail 관련 클래스, User에 송금 타입 설정 등을 주로 수정해서 코드 리뷰 하실 때, 그런 클래스만 중점적으로 보셔도 좋을 것 같습니다!
코드가 조금 지저분해진 것 같은데 그런 부분이 있다고 여기시면 지적해 주시면 감사하겠습니다! 늦게 제출하게 되어 죄송합니다.

- 기존 AccountService에서 가독성과 유지보수를 위해 분리
- 기존 템플릿을 사용하는 곳에서 커서를 외부에서 넣어주기에 Supplier로 변경
- 임시 테이블에 bulk insert 하고 JOIN으로 bulk update 하도록 하여 쿼리 횟수를 최소화
@ZZAMBAs ZZAMBAs self-assigned this Feb 23, 2025
@ZZAMBAs ZZAMBAs merged commit 344a2a7 into base/zzambas Feb 23, 2025
1 check failed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant