Skip to content

Commit

Permalink
[test] photo_request 테이블에 비관적 락을 적용해 동시성 문제 해결하기
Browse files Browse the repository at this point in the history
  • Loading branch information
RumosZin committed Sep 5, 2024
1 parent 3c69103 commit 4210ea3
Show file tree
Hide file tree
Showing 4 changed files with 13 additions and 34 deletions.
12 changes: 0 additions & 12 deletions src/main/java/gdsc/cau/puangbe/photo/entity/PhotoRequest.java
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,6 @@ public class PhotoRequest {
@OneToMany(mappedBy = "request", cascade = {CascadeType.PERSIST, CascadeType.REMOVE})
private List<PhotoOrigin> photoUrls = new ArrayList<>();

@Version
private Long version;

@Builder
public PhotoRequest(User user, Gender gender, List<String> urls, String email) {
this.user = user;
Expand All @@ -69,13 +66,4 @@ public void modifyEmail(String email) {
this.email = email;
this.updateDate = LocalDateTime.now();
}

@Override
public String toString() {
return "PhotoRequest{" +
"id=" + id +
", email='" + email + '\'' +
", version=" + version +
'}';
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,11 @@

@Repository
public interface PhotoRequestRepository extends JpaRepository<PhotoRequest, Long> {

@Lock(LockModeType.PESSIMISTIC_WRITE)
Optional<PhotoRequest> findById(Long photoRequestId);

// 특정 유저의 최근에 만들어진 PhotoRequest 조회
@Lock(LockModeType.PESSIMISTIC_WRITE)
Optional<PhotoRequest> findTopByUserIdOrderByCreateDateDesc(Long photoRequestId);

This comment has been minimized.

Copy link
@RumosZin

RumosZin Sep 6, 2024

Author Contributor

비관적 락은 데이터베이스의 락 기능을 이용하는 것입니다. 동시에 같은 레코드에 접근할 것으로 예상되는 곳에 @Lock(LockModeType.PESSIMISTIC_WRITE)를 걸어서 비관적 락을 적용합니다.

기존에는 save 시에 select - update가 이루어졌다면, 비관적 락을 사용하면 select for update - update가 이루어져 조회 시에도 레코드에 배타적 잠금을 걸 수 있습니다.

}
24 changes: 9 additions & 15 deletions src/main/java/gdsc/cau/puangbe/photo/service/PhotoServiceImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -42,12 +42,6 @@ public class PhotoServiceImpl implements PhotoService {
// 완성된 요청 id 및 imageUrl을 받아 저장
@Override
@Transactional
@Lock(LockModeType.OPTIMISTIC)
@Retryable(
retryFor = {ObjectOptimisticLockingFailureException.class},
maxAttempts = 1000,
backoff = @Backoff(100)
)
public void uploadPhoto(Long photoRequestId, String imageUrl) {
// 예외처리
PhotoRequest photoRequest = photoRequestRepository.findById(photoRequestId)
Expand All @@ -65,18 +59,18 @@ public void uploadPhoto(Long photoRequestId, String imageUrl) {
photoResult.update(imageUrl);
photoResultRepository.save(photoResult);

log.info("uploadPhoto - PhotoRequest version: {}", photoRequest.getVersion());
log.info("upload photo");


// 이메일 발송
EmailInfo emailInfo = EmailInfo.builder()
.email(photoRequest.getEmail())
.photoUrl(imageUrl)
.name(user.getUserName())
.framePageUrl("https://www.google.com/") // TODO : 프론트 분들 링크 관련 답변 오면 프레임 페이지 링크 관련 수정
.build();

sendEmail(emailInfo);
// EmailInfo emailInfo = EmailInfo.builder()
// .email(photoRequest.getEmail())
// .photoUrl(imageUrl)
// .name(user.getUserName())
// .framePageUrl("https://www.google.com/") // TODO : 프론트 분들 링크 관련 답변 오면 프레임 페이지 링크 관련 수정
// .build();
//
// sendEmail(emailInfo);
}

// 특정 요청의 imageUrl 조회
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -131,12 +131,6 @@ public String getRequestStatus(Long userId){

@Override
@Transactional
@Lock(LockModeType.OPTIMISTIC)
@Retryable(
retryFor = {ObjectOptimisticLockingFailureException.class},
maxAttempts = 1000,
backoff = @Backoff(100)
)
public Long updateEmail(Long userId, String email) {

// 가장 최근의 PhotoRequest 조회
Expand All @@ -146,7 +140,7 @@ public Long updateEmail(Long userId, String email) {
photoRequest.modifyEmail(email);
photoRequestRepository.save(photoRequest);

log.info("updateEmail - PhotoRequest version: {}", photoRequest.getVersion());
log.info("update email");

return photoRequest.getId();
}
Expand Down

0 comments on commit 4210ea3

Please sign in to comment.