병원 예약 시스템에서 결제 프로세스는 여러 복잡한 요소들이 얽혀있습니다. 예약 정보 검증, 결제 처리, 데이터 정합성 유지 등 다양한 단계들이 순차적으로 실행되어야 하며, 각 단계별로 적절한 예외 처리가 필요합니다. 이러한 복잡한 프로세스를 체계적으로 설계하고 구현하기 위해 시퀀스 다이어그램을 활용했습니다.
- 전체 프로세스의 명확한 시각화
- 각 컴포넌트 간의 상호작용 정의
- 예외 상황에 대한 체계적인 처리 흐름 설계
- Redis를 활용한 동시성 제어 포인트 명확화
예약 프로세스
- 클라이언트가 필수 정보(병원 ID, 예약 날짜, 예약 시간)와 함께 예약 요청
- 서비스 레이어에서 Redis를 통한 진행 중인 예약 여부 확인
- 예약 가능 여부 검증 후 임시 예약 정보를 Redis에 저장
- DB를 통한 최종 예약 가능 여부 확인
결제 프로세스
- 포트원 API를 통한 결제 정보 획득
- 결제 컨트롤러에서 필수 정보 검증
- 병원 정보와 사용자 정보 유효성 검증
- 결제 내역 저장 및 예약 정보 최종 등록
- Redis의 임시 예약 정보 삭제
예외 처리
- 진행 중인 예약 존재 시 예외 처리
- 이미 예약된 시간대 처리
- 결제 실패 시 Redis 데이터 정리
- 사용자/병원 정보 누락 시 처리
@Transactional(readOnly = true) public ReservationIsvalidAndLockResponse isValidReservaion(ReservationSaveRequest request){ // 레디스에 예약중인지 체크 if(!applicationLockClient.isvalidRedisKey(request.getHospId(), request.getReservationAt(), request.getReservationTime())) { throw new RuntimeException(); } // 키값을 락을 걸어 키를 레디스에 저장후 락을 푼다. String redisKey = reservationLock(request); // false면 예약이 가능하다. Boolean isvalid = hospitalReservationRepository.findByHospIdAndReservationDateAndReservationTime(request).isPresent(); if(isvalid) applicationLockClient.remove(redisKey); return new ReservationIsvalidAndLockResponse(redisKey, isvalid); }
주요 처리 단계
진행 중인 예약 확인
동시성 제어
최종 유효성 검증
@Transactional public Boolean createPayment(CreatePaymentRequest createPaymentRequest){ // 트랜잭션 완료 후 Redis 락 해제를 보장하기 위한 동기화 설정 TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronizationAdapter() { @Override public void afterCompletion(int status) { releaseLock(createPaymentRequest.getRedisKey()); } }); Optional<HospitalEntity> isValidHospital = hospitalRepository.findById(createPaymentRequest.getHospId()); Optional<SocialUserEntity> isValidUser = socialUserJpaRepository.findByProviderId(createPaymentRequest.getProviderId()); // 결제 유저, 병원 있는지 체크 if(isValidUser.isPresent() && isValidHospital.isPresent()){ PaymentEntity payment = PaymentEntity.from(createPaymentRequest, isValidHospital.get(), isValidUser.get()); PaymentEntity createdPayment = paymentRepository.save(payment); // 결제정보를 저장되었는지 HospitalReservationEntity hospitalReservation = HospitalReservationEntity.from(createPaymentRequest, isValidUser.get(), isValidHospital.get(), createdPayment); hospitalReservationService.createReservation(hospitalReservation); } return false; }
주요 처리 단계
트랜잭션 동기화 설정
데이터 유효성 검증
결제 및 예약 처리
시퀀스 다이어그램을 통한 설계는 복잡한 예약-결제 프로세스의 흐름을 시각화하고, 컴포넌트 간의 상호작용을 명확히 파악할 수 있게 해주었습니다. 이러한 설계를 바탕으로 Redis를 활용한 동시성 제어와 트랜잭션 처리를 구현하여, 분산 환경에서도 안정적으로 동작하는 예약 시스템을 구축할 수 있었습니다.