Skip to content

Commit

Permalink
feat: Optimistic Lock to like
Browse files Browse the repository at this point in the history
  • Loading branch information
Minuooooo committed Jul 11, 2024
1 parent 44db52a commit 9d350fe
Show file tree
Hide file tree
Showing 4 changed files with 39 additions and 18 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ public class PostLikeController {
@ResponseStatus(OK)
@PostMapping()
public Response togglePostLike(Long postId) {
postLikeService.togglePostLike(postId, memberService.getCurrentMember());
postLikeService.like(postId, memberService.getCurrentMember());
return success(SUCCESS_TO_TOGGLE_POST_LIKE);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,5 @@
import java.util.Optional;

public interface PostLikeRepository extends JpaRepository<PostLike, Long> {
@Lock(LockModeType.PESSIMISTIC_WRITE) // 동시성 문제 방지를 위해 Pessimistic lock 사용
Optional<PostLike> findByPostIdAndLikerId(Long postId, Long likerId);
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,37 +8,59 @@
import greeny.backend.exception.situation.PostNotFoundException;
import greeny.backend.exception.situation.SelfLikeNotAllowedException;
import lombok.RequiredArgsConstructor;
import org.springframework.dao.OptimisticLockingFailureException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Optional;

@Service
@RequiredArgsConstructor
public class PostLikeService {

private final PostLikeRepository postLikeRepository;

private final PostRepository postRepository;

// 좋아요 or 취소

@Transactional
public void togglePostLike(Long postId, Member liker) {
Optional<PostLike> postLike = postLikeRepository.findByPostIdAndLikerId(postId, liker.getId());
// 이미 좋아요 눌렀는지 확인
if(postLike.isEmpty()) likePost(postId, liker); // 안 눌렀다면 좋아요 수행
else postLikeRepository.delete(postLike.get()); // 이미 눌렀다면 취소 수행

public void like(Long postId, Member liker) {
boolean retry;
do {
try {
retry = false;
Optional<PostLike> foundPostLike = findPostLike(postId, liker.getId());
toggle(postId, liker, foundPostLike);
}
catch (OptimisticLockingFailureException e) {
retry = true;
}
} while (retry);
}

// 게시글 좋아요
public void likePost(Long postId, Member liker){
Post post = postRepository.findByIdWithWriter(postId).orElseThrow(PostNotFoundException::new);
if(post.getWriter().getId().equals(liker.getId())) throw new SelfLikeNotAllowedException(); // 자기의 게시글에는 좋아요를 누를 수 없음
public void create(Long postId, Member liker) {
Post post = getPost(postId);
if (post.getWriter().getId().equals(liker.getId()))
throw new SelfLikeNotAllowedException();
postLikeRepository.save(PostLike.builder()
.post(post)
.liker(liker)
.build());
}

public Post getPost(Long postId) {
return postRepository.findByIdWithWriter(postId).orElseThrow(PostNotFoundException::new);
}

public Optional<PostLike> findPostLike(Long postId, Long likerId) {
return postLikeRepository.findByPostIdAndLikerId(postId, likerId);
}

private void delete(PostLike postLike) {
postLikeRepository.delete(postLike);
}

private void toggle(Long postId, Member liker, Optional<PostLike> postLike) {
if (postLike.isEmpty()) {
create(postId, liker);
return;
}
delete(postLike.get());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ public void editPostInfo(Long postId, WritePostRequestDto editPostInfoRequestDto
}

@Transactional
protected void uploadPostFileList(List<MultipartFile> multipartFiles, Post post) {
public void uploadPostFileList(List<MultipartFile> multipartFiles, Post post) {
// s3에 파일을 업로드 한 뒤 예외가 발생하면 db는 롤백이 되지만,
// 이미 s3에 저장된 이미지는 삭제되지 않는 문제가 있음.

Expand Down

0 comments on commit 9d350fe

Please sign in to comment.