Spring

Redis 동시성 제어 (수정중)

sehunbang 2024. 3. 22. 15:55

구현

@Transactional
public Long updateBoard(Long boardId, BoardRequest boardRequest, User user) {

    Board board = getBoardById(boardId);

    RLock lock = redissonClient.getFairLock("board:" + boardId);
    try {
        // tryLock 메소드를 사용하여 10초 동안 락을 획득 시도, 최대 60초 동안 락 유지
        if (lock.tryLock(10, 60, TimeUnit.SECONDS)) {
            try {
                // 락을 성공적으로 획득한 경우의 처리
                checkBoardStateIsTrue(board);
                validateBoardOwner(user, board);
                updateBoardAttributes(board, boardRequest);
            } finally {
                lock.unlock();
            }
        } else {
            throw new IllegalArgumentException("다른 유저가 접근중에 있습니다. 다시 시도해 주세요");
        }
    } catch (InterruptedException e) {
        Thread.currentThread().interrupt();
    }
    return board.getId();
}

 

 

 

어노테이션 으로 간단하게 해결

@Transactional
@WithDistributedLock(lockName = "#user.getId")
@CachePut(value = "User", key = "#user.getId", cacheManager = "cacheManager")
public Long update(UpdateRequestDto requestDto, User user) {
    Long returnlong;
    User updateuser = userRepository.findById(user.getId())
        .orElseThrow(NoSuchElementException::new);
    String newpass = passwordEncoder.encode(requestDto.getPassword());
    requestDto.setPassword(newpass);
    updateuser.update(requestDto);
    returnlong = updateuser.getId();
    return returnlong;
}