@Test
@DisplayName("한 코치의 하나의 면담 가능 시간으로 동시에 여러개의 면담을 생성할 수 없다. - 동시성")
void concurrentCreate() throws InterruptedException {
final int numberOfThreads = 2;
final ExecutorService service = Executors.newFixedThreadPool(numberOfThreads);
final CountDownLatch start = new CountDownLatch(numberOfThreads);
final CountDownLatch end = new CountDownLatch(numberOfThreads);
coachService.putAvailableDateTimesByCoachId(준.getId(), 면담가능시간생성요청정보_2022_07_01_10_TO_12);
for (long i = 5L; i < 5 + numberOfThreads; i++) {
final long finalI = i;
service.execute(() -> {
try {
start.countDown();
start.await();
interviewService.create(finalI, 면담생성요청정보_준_2022_07_01_10_00);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
end.countDown();
}
});
}
end.await();
final ScheduleResponse response = interviewService.findAllByCoach(준.getId(), 2022, 7);
assertThat(response.getCalendar()).hasSize(1);
}
1. serializable + not unique
데드락이 발생합니다.
innoDB의 serializable은 기본적으로 모든 단순읽기에도 s lock을 걸기때문에
인터뷰가 생성될때
tx1 이 availableDateTime의 레코드를 읽으며 s lock을 걸고
tx2 가 availableDateTIme의 레코드를 읽으며 s lock을 건다.
tx1이 availableDateTime 을 수정하려고 x lock을 걸때 tx2의 s lock 때문에 기다린다.
tx2이 availableDateTime 을 수정하려고 x lock을 걸때 tx1의 s lock 때문에 기다린다.
이러한 문제로 데드락이 발생합니다.
-> 틀린 설명
현재 테스트코드는 H2로 돌아가는데 H2 의 serializable은 innoDB처럼 돌아가지 않습니다. (읽기에 slock을 거는 것이 아닙니다)
그럼 데드락이 왜 터질까?
2. repeatable read + not unique
동시성 문제가 발생합니다.
unique가 걸려있지 않기 때문에 2개의 Interview가 동시에 생성이 되었습니다.
3. repleatable read + unique
unique 제약조건으로 DB에러가 터집니다.
Caused by: org.h2.jdbc.JdbcSQLIntegrityConstraintViolationException: Unique index or primary key violation: "PUBLIC.UK_89AEH6C8PV4YAQSUYDVIE7QE_INDEX_C ON PUBLIC.INTERVIEW(AVAILABLE_DATE_TIME_ID NULLS FIRST) VALUES ( /* 1 */ CAST(1 AS BIGINT) )"; SQL statement:
insert into interview (id, available_date_time_id, coach_id, crew_id, interview_end_time, interview_start_time, interview_status_type) values (default, ?, ?, ?, ?, ?, ?) [23505-214]
동시에 Interview가 생기지 않기 때문에 이대로 해결하는 방식이 좋아 보입니다.
DB에러이기 때문에 500에러가 터지는데 500 에러로 두는 것과 400에러로 바꾸는 방식중에는 회의를 해봐야할 것 같습니다!
Issues
논의사항
동시성 테스트
코드
1. serializable + not unique
데드락이 발생합니다.
innoDB의 serializable은 기본적으로 모든 단순읽기에도 s lock을 걸기때문에
인터뷰가 생성될때
이러한 문제로 데드락이 발생합니다. -> 틀린 설명
현재 테스트코드는 H2로 돌아가는데 H2 의 serializable은 innoDB처럼 돌아가지 않습니다. (읽기에 slock을 거는 것이 아닙니다) 그럼 데드락이 왜 터질까?
2. repeatable read + not unique
동시성 문제가 발생합니다.
unique가 걸려있지 않기 때문에 2개의 Interview가 동시에 생성이 되었습니다.
3. repleatable read + unique
unique 제약조건으로 DB에러가 터집니다.
동시에 Interview가 생기지 않기 때문에 이대로 해결하는 방식이 좋아 보입니다.
DB에러이기 때문에 500에러가 터지는데 500 에러로 두는 것과 400에러로 바꾸는 방식중에는 회의를 해봐야할 것 같습니다!
close #510