Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: DELETE/timetable 동시성 에러 #743

Merged
merged 2 commits into from
Aug 1, 2024

Conversation

kwoo28
Copy link
Contributor

@kwoo28 kwoo28 commented Jul 31, 2024

🔥 연관 이슈

🚀 작업 내용

DELETE/timetable API 동시 호출과정에서 ObjectOptimisticLockingFailureException 에러가 발생했습니다.

  • ObjectOptimisticLockingFailureException란?
    JPA에서 매핑된 객체에 대한 낙관적 잠금 위반에 대해 발생한 예외를 말합니다. 즉, DB단이 아닌 어플리케이션의 JPA 영속성단에서 레코드를 수정하기 전에 다른 트랜잭션이 해당 레코드를 수정했는지를 확인하고 발생시킵니다.

트랜잭션A : 조회 -> 삭제
트랜잭션B : 조회 -> 삭제

현재 위와같은 삭제API가 동시에 호출되면서 트랜잭션 충돌이 발생하여 JPA에서 ObjectOptimisticLockingFailureException 예외가 발생되었습니다.

해결방안1 - 조회메서드에 비관적락을 건다.
조회메서드에 비관적락을 걸게되면 예외가 발생하지 않고 간단하게 처리됩니다. 하지만 해당 레코드에 많은 트랜잭션의 접근이 발생시 지연이 발생합니다.

해결방안2 - try-catch문으로 예외처리한다.
만약 현재 단순 조회->삭제 로직에서 조회메서드에 락을 걸게된다면 얻는 이익은 예외가 발생 안한다뿐입니다. 그렇기때문에 예외를 발생시키지 않기위해 성능저하를 감수하는것은 올바르지 못한 방향이라 생각이 들었기에, try-catch문을 통해 단순 요청이 빠르다는 정보를 클라이언트에게 넘겨줍니다.

그래서 현재 상황에서 최적의 방안은 해결방안2라고 생각이들어 try-catch문으로 해결했습니다.

💬 리뷰 중점사항

@kwoo28 kwoo28 self-assigned this Jul 31, 2024
@github-actions github-actions bot added the 버그 정상적으로 동작하지 않는 문제상황입니다. label Jul 31, 2024
@github-actions github-actions bot requested a review from ImTotem July 31, 2024 07:32
Copy link

github-actions bot commented Jul 31, 2024

Unit Test Results

  29 files    29 suites   3m 6s ⏱️
257 tests 256 ✔️ 1 💤 0
258 runs  257 ✔️ 1 💤 0

Results for commit 7dee87f.

♻️ This comment has been updated with latest results.

throw AuthorizationException.withDetail("userId: " + userId);
}
timetableLectureRepositoryV2.deleteById(timetableLectureId);
entityManager.flush();
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

JPA에선 트랜잭션 충돌을 커밋 or flush할 당시에 감지합니다. 그래서 flush를 하지 않는다면, try범위 밖에서 커밋되면서 예외가 발생되어 잡지 못합니다. 그래서 try문 범위 안에서 예외를 발생시킬 수 있도록 flush 코드를 추가했습니다.

Copy link
Contributor

@duehee duehee left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

저번에 Frame에서의 동시성 문제는 배타적 락을 걸어서 해결했었던 것 같은데, 이번에는 다른 방법이네요! 발생 이유와 각 해결방안의 비교를 통해 적용하신 점이 인상 깊습니다 :D
잘 배워갑니다! 고생하셨어요~

Comment on lines +607 to +608
ExecutorService executor = Executors.newFixedThreadPool(2);
CountDownLatch latch = new CountDownLatch(2);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A

최근에 동시성 문제가 많이 발생하는데, 코드 리뷰하는 과정에서 참 많이 배우게 되는 것 같아요!👍

Copy link
Contributor

@ImTotem ImTotem left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

동시성 어렵네요...

@kwoo28 kwoo28 merged commit 812f13c into develop Aug 1, 2024
4 checks passed
@kwoo28 kwoo28 deleted the fix/741-delete-timetable-concurrency branch August 1, 2024 02:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
버그 정상적으로 동작하지 않는 문제상황입니다.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

시간표 삭제 동시성 발생
3 participants