Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/nyh365 step4 #34

Open
wants to merge 75 commits into
base: base/nyh365
Choose a base branch
from
Open

Feature/nyh365 step4 #34

wants to merge 75 commits into from

Conversation

nyh365
Copy link

@nyh365 nyh365 commented Feb 18, 2025

구현 요구 사항

  • 송금 시 송금 사용자의 설정에 따라 바로 송금이 이뤄지지 않을수도 있습니다. 이 경우 금액을 받는 사용자가 직접 확인 후 금액을 받아야 합니다.
  • Pending 상태로 머물러 있는 최대 기한은 72시간이며, 24시간이 남았을 시 금액을 받는 사용자에게 Remind 알림이 발송됩니다.

구현

  • 지연 송금
    • 기존 송금 트랜잭션에 타입을 추가하여 지연 송금인지 즉시 송금인지 구별하도록 했습니다.
    • A->B로의 송금에서 지연 송금의 경우 A의 잔액 차감 후 송금 내역에 대한 데이터를 저장하는 과정을 하나의 트랜잭션에서 처리하도록 했습니다.
  • 72시간 후 송금 취소
    • 1분마다 스케줄러를 통해 72시간이 지난 송금에 대해 취소하도록 구현했습니다.
    • 송금 타입이 'PENDING'이고 송금 상태가 'PENDING'인 송금 내역을 찾아 송금 취소 관련 메세지를 메세지 큐에 전달하도록 구현했습니다.
  • Remind 알림
    • 1분마다 스케줄러를 통해 24시간이 남은 송금에 대해 알림을 보내도록 구현했습니다.

보완해야할 부분

  • 현재 24시간 남은 송금이나, 72시간 지난 송금에 대해 조회할 때 제한 없이 데이터들을 가져오고 있는데, 페이징 처리로 변경할 예정입니다.
  • 현재 알림 기능 관련해서 로그로 알림이 갈 것이다라고 처리한 상황입니다.

nyh365 added 30 commits January 27, 2025 16:57
- 다중환경에서 lost update로 인한 데이터 적합성 문제를 해결하기 위해 락을 사용했습니다.
- 은행 업무에서는 데이터 무결성을 지키는게 중요하다고 생각해서 비관적 락을 사용했습니다.
- 다중 환경에서 lost update로 인한 데이터 무결성 해결을 위해 비관적 락 사용
- 이후 확장성을 위해 int에서 long으로 변경
- 이후 확장성을 위해 int에서 long으로 변경
- 송금 내역 저장을 위함
- 메세지 큐에 메세지 전송을 위함
- 이벤트 리스너가 비동기적으로 실행되도록 하기 위함
- 이벤트 리스너를 통해 수령인의 잔액 업데이트 로직 분리
- 메세지 큐를 통해 수령인의 잔액 업데이트
Copy link

@opixxx opixxx left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

수고하셨습니다. 간단하게 의견 남겼습니다

AND t.type = :type
AND t.createDate = :targetTime
""")
List<TransferTransaction> findPendingTransactions(@Param("status") TransactionStatus status,
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

t.createDate = :targetTime처럼 동등조건으로 필터링한 이유가 있을까요? 스케줄러가 돌고 그 다음 스케줄러가 도는 그 빈 시간동안 데이터가 누락될 것 같은 느낌이 들어요

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

알림 전송 여부를 아직 추가를 못한 상태라 중복 발송될 것이라 생각해 임시로 동등 조건으로 해두었습니다. 알림 관련 기능 추가 후 범위 조건으로 변경할 예정입니다.

}

@Transactional
public void acceptTransfer(Long transferTransactionId, TransferAcceptReq transferAcceptReq) {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

지연 송금의 경우 메시지 큐를 사용하지 않은 이유가 있을까요?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

메시지 큐를 사용한 이유가 A->B로 송금 시 1. 락을 가지고 A 계좌 잔액 차감 2. 송금 내역 추가 3. B 계좌 잔액 증액 인데 트랜잭션이 길다 보니 3번 과정을 분리하기 위해 사용했었습니다. 근데 해당 기능에서는 2번과 3번의 과정만 거치기 때문에 따로 메시지 큐를 사용하지 않았습니다.

@Slf4j
@Service
@RequiredArgsConstructor
public class TransactionService {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

지연 송금에서 sender가 송금 취소하는 기능이 안보여요

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

해당 기능을 따로 추가 못했습니다. 반영해서 올리겠습니다.


@Transactional
public void acceptTransfer(Long transferTransactionId, TransferAcceptReq transferAcceptReq) {
TransferTransaction transferTransaction = transferTransactionRepository.findByIdAndStatus(transferTransactionId,
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

동시에 accept, cancel 요청이 들어오면 어떻게 되나요?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

현재 update 쿼리를 이용해서 accept, cancel 처리를 하고 있습니다. 동시에 accept, cancel 요청이 온다면 둘 중 하나는 transaction status가 update 조건에 해당하지 않아 update를 못하게 되고 이후 검증 로직에서 오류를 던져 롤백하도록 구현했습니다.

Copy link

@hellozo0 hellozo0 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

수고하셨습니다!

메시지큐의 롤백 과정이나 동작원리를 잘 알지 못해서 대략적인 흐름만 훑어봤습니다!
송금 & 상태 변경을 한번의 트랜잭션 단위로 묶어서 처리하는 거 같은데, 메시지큐에 상반되는 내용들이 들어왔을때 어떻게 처리하는지가 궁금하네요... (송금수락&취소가 동시에 생길일이 없거나 적겠지만, 송금 실패로 재 송금 처리 중에 취소처리가 들어오거나 해서 상태가 가로채기 되었을때?)

Comment on lines +47 to +50

List<TransferTransaction> transferTransactions = transferTransactionRepository.getTransferTransactionsByStatusAndType(
TransactionStatus.PENDING, TransactionType.IMMEDIATE);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

해당 함수가 메시지큐에서 송금처리가 제대로 되지 않았을 경우에, 비정상 송금 내역을 찾아서 다시 메시지큐에 넣는 함수로 이해했는데,

그렇다면 해당 이벤트를 다시 발행하는 동안 송금 취소 트랜잭션이 실행되면 어떻게 되나요??

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

메시지를 처리할 때 들어온 메시지(비정상 송금 내역)가 조건에 해당하는지(송금 취소 안된 송금 내역인지) 확인하는 로직이 있습니다. 그래서 메세지를 처리하는 동시에 송금 취소 트랜잭션이 실행되어도 둘 중 하나만 처리되도록 구현한 상태입니다.

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.

3 participants