我不确定是否应该在我的 Spring Boot 项目中组合或分离这两种方法

问题描述 投票:0回答:1
有一个方法

afterMissionComplete()

执行任务并进行后处理,还有一个方法
sendNotificationToUsersInRoom()
在执行任务后向同一组的成员发送通知。

// After mission complete. Create mission log, Do user progression @PostMapping("/complete") @ResponseStatus(HttpStatus.CREATED) public BaseResponse<MissionLogCreateRes> postMissionLog( @Parameter(hidden = true) @AuthUser Integer userId, @RequestBody @Valid MissionLogCreateReq missionLogCreateReq ) { UserStat userStat = missionService.afterMissionComplete(userId, missionLogCreateReq); if (Objects.nonNull(missionLogCreateReq.getRoomId())) { notificationService.sendNotificationToUsersInRoom(missionLogCreateReq.getAlarmId(), userId); } return new BaseResponse<>(Status.SUCCESS_CREATED, new MissionLogCreateRes(userStat)); }
    @Transactional
    public UserStat afterMissionComplete(int userId, MissionLogCreateReq req) {
        User user = userRepository.findById(userId)
                .orElseThrow(() -> new BaseException(Status.USER_NOT_FOUND));

        createMissionLog(user, req);
        userService.userProgress(user);

        return UserStat.from(user);
    }
    public void sendNotificationToUsersInRoom(Integer alarmId, Integer missionCompleteUserId) {

        User user = userRepository.findById(missionCompleteUserId)
                .orElseThrow(() -> new BaseException(Status.USER_NOT_FOUND));
        Room room = roomRepository.findByAlarmId(alarmId)
                .orElseThrow(() -> new BaseException(Status.ROOM_NOT_FOUND));

        List<Integer> userIdsInRoom = room.getRoomUsers().stream()
                .map(RoomUser::getUser)
                .map(User::getId)
                .filter(userId -> userId != user.getId())
                .collect(Collectors.toList());

        if (userIdsInRoom.size() > 0)
            fcmService.sendMessageToTokens(
                    new RoomMissionLogNotificationVo(
                            user,
                            room,
                            fcmTokenRepository.findAllByUser_IdIn(userIdsInRoom)

                    )
            );
    }
我认为我们应该像当前控制器代码一样将这两个方法分开,但我的同事说我们应该在 

sendNotificationToUsersInRoom()

 中包含 
afterMissionComplete()
,以便这两个功能都在一个事务中执行。

但是,即使通知失败,我也不赞成不运行任务后流程。

您认为应该怎样做?请自由发表您的意见。

java spring-boot oop coding-style spring-transactions
1个回答
0
投票
您希望让 sendNotification 的重要性低于整个流程的情况并不罕见,尤其是在响应数据库事件时发生的电子邮件或其他消息传递;有时您希望进行输入,但如果通知电子邮件失败,您不希望它终止整个业务运营。

我会将 sendNotification 调用移至 afterComplete 方法中,因为这是您希望在完成后发生的事情,并且将两者绑定在一起在商业上是有意义的。

为了防止失败的 sendNotification 回滚整个操作,您可以将其包装在 try{} catch 块中以捕获失败并记录异常,但让进程继续而不回滚操作。如果电子邮件/通知不重要,我会经常对与电子邮件相关的交易执行此操作。

@Transactional public UserStat afterMissionComplete(int userId, MissionLogCreateReq req) { User user = userRepository.findById(userId) .orElseThrow(() -> new BaseException(Status.USER_NOT_FOUND)); createMissionLog(user, req); userService.userProgress(user); try{ if (Objects.nonNull(missionLogCreateReq.getRoomId())) { notificationService.sendNotificationToUsersInRoom(missionLogCreateReq.getAlarmId(), userId); } } catch (ex Exception) { logMyException(ex) } return UserStat.from(user); }
    
© www.soinside.com 2019 - 2024. All rights reserved.