티스토리 뷰

반응형

이번에는 트랜잭션 관심 분리와 애플리케이션 이벤트 활용에 대해 설계문서를 작성해볼 것입니다.

시나리오는, 좌석 예약 시나리오로 플로우는 다음과 같다.

1 예약정보 저장 
2 계좌 정보에 고객정보 있는지 확인
2.1 계좌 정보에 고객 정보가 없다면 계좌 정보에 고객 정보 생성
3 결제 내역 생성
4 결제 히스토리에 결제 
5 해당 고객 계좌 정보에 차감금액 입력

위 플로우는 하나의 트랜잭션으로 묶인다.

코드는 다음과 같다.

    @DistributedLock(key="#userId")
    public boolean payForPreReservedSeat(int amount, Long userId) throws Exception {
        Reservation reservation = jpaReservationCoreRepository.savePaymentReservationInfo( userId );
        try{
            jpaAccountCoreRepository.findByUserId(userId);
        } catch (Exception e) {
            User user = jpaUserCoreRepository.getById(userId);
            jpaAccountCoreRepository.createUserAccount(user);
        }
        User user = jpaUserCoreRepository.getById(userId);
        try {
            jpaPaymentCoreRepository.insertPaymentInfo(
                    user, reservation, amount
            );
        } catch (Exception e) {
            throw new AlreadyPaidException();

        }

        Account account = jpaAccountCoreRepository.findByUserId(userId);
        jpaAccountHistoryCoreRepository.createPaymentAccountHistory(account, amount, "Payment");
        jpaAccountCoreRepository.decreaseAmountFromAccount(user.getId(), amount);
        return true;
    }

전체적인 흐름은 DistributedLock 분산락과 한 트랜잭션을 이용해 동시성을 제어한다.

추가 과제 사항으로 여기서 가정을 둘 것인데 예약 저장 계좌 정보 변경을 한 트랜잭션으로 묶인 것을 분리 할 것이다. 분리가 고려되는 사항은 다음과 같다.

1 다수의 SlowRead 작업으로 인해 요청 처리에 영향을 줄 수 있음
2 긴 생명 주기의 Transaction의 경우, 오랜 시간 소요되나 후속작업이 실패함에 따라 전체 프로세스가 롤백될 수 있음

1번과 2번을 피할 수 있는 방법으로 트랜잭션을 분리하는 방법이 고려될 수 있다.

그렇다면 트랜잭션을 분리해야하는데 어떻게 할 수 있을까? 두 도구를 활용하여 해결할 것인데, 하나는 spring의 앱 이벤트 리스너, 퍼블리셔 그리고 메시지 브로커 이다. 트랜잭션이 끝났을 때 메시지 브로커로 메시지를 쏘아올리고 메시지 브로커가 메시지를 수집하는 과정을 앱 이벤트 리스너, 퍼블리셔로 해당 트랜잭션을 수행하도록 처리할 것이다. 만약 분리된 트랜잭션이 실패할 경우 과정에서 처리된 트랜잭션을 적절히 롤백하도록 할 것이다.

메시지 브로커로는 Rabbit MQ, redis, Kafka 등이 있는데 나는 Kafka를 쓸 것이다. 기술 선정이유는 kafka가 메시지 브로커현업에서 많이 사용되므로 선택하게 되었다.

분리할 트랜잭션 프로세스를 정리하자면,

1 예약정보 저장 
---- 분리
1 계좌 정보에 고객정보 있는지 확인
1.1 계좌 정보에 고객 정보가 없다면 계좌 정보에 고객 정보 생성
2 결제 내역 생성
3 결제 히스토리에 결제 
4 해당 고객 계좌 정보에 차감금액 입력
---- 만약 결제 실패시 실패시
1 예약정보 파기

로 처리할 것이다.

문서 끝

반응형