728x90
오버부킹(Overbooking) 이란
오버부킹 이슈는 여러명의 사용자가 동시에 같은 자원을 예약하려고할 때 발생한다.
문제상황 제시
현재 SKKA프로젝트 도메인에서 오버부킹 이슈가 발생할 수 있는 가능성이 많다고 생각된다.
대표적으로 특정해 몇월 몇일에 스케줄을 예약하려고 하는데, 마침 그 날이 수요가 많은 날일 때 예약하려고 하는 요청들이 몰릴 것이다.
그렇게 된다면 처음에 해당 날짜에 예약을 요청한 사용자가 예약에 성공 해야 공정하고 투명한 시스템이 될 것 같다.
< 예시 >
[현재 테이블 상황]
id | customer_id | study_seat_id | started_time | end_time |
---|---|---|---|---|
1 | 1 | 1 | 2023-12-01 11:12:00 | 2023-12-01 13:12:00 |
2 | 2 | 2 | 2023-12-01 14:12:00 | 2023-12-01 16:12:00 |
3 | 3 | 3 | 2023-12-01 18:12:00 | 2023-12-01 20:12:00 |
[1번 요청]
POST /seats/1 {
"customerId" : 1,
"startedTime" : "2023-12-01T09:00:00",
"endTime" : "2023-01-10T11:00:00"
}
[2번 요청]
POST /seats/1 {
"customerId" : 2,
"startedTime" : "2023-12-01T09:00:00",
"endTime" : "2023-01-10T11:00:00"
}
[3번 요청]
POST /seats/1 {
"customerId" : 3,
"startedTime" : "2023-12-01T09:00:00",
"endTime" : "2023-01-10T11:00:00"
}
1, 2, 3번 요청이 한꺼번에 요청이 쏟아졌을 때 제일 먼저 온 요청만 처리 해야하고 나머지는 이미 차지 되었다는 에러를 던져야한다.
해결방안 모색
- lock
- ORM (jpa)
- ORM 레이어에서 락을 사용하면 더 높은 추상화 수준을 제공해서 락 로직을 데이터베이스 대신 애플리케이션 코드에서 처리할 수 있다.
그러면 개발 프로세스가 간소화될 것 같고, 특히 동시 트랜잭션이 많은 애플리케이션에서 성능이 향상될 수 있을 것 같다.
그러나 덜 견고하거나 확장 가능하지 않을 수 있으며 일관성을 유지하고 교착 상태를 피하기 위해 추가적인 관리가 필요할 수 있을 것 같다. - DB
- 데이터베이스(DB) 레이어의 락은 데이터베이스 수준에서 구현되므로 애플리케이션 코드와 독립적이므로 더 신뢰성이 높고 견고하다.
여기서 신뢰성이 높고 견고하다는 의미는 네트워크 장애, 하드웨어 오류, 잘못된 애플리케이션 사용 등 예기치 못한 상황에서도 데이터베이스는 올바르게 작동 하고 오류 없이 기능한다는 것을 보장하는 것을 말한다.
그리고 복잡한 데이터 관계나 여러 애플리케이션이 동일한 데이터베이스에 액세스하는 경우 특히 효과적이다. 그러나
구현과 관리가 더 복잡할 수 있고, 성능에 더 큰 영향을 미칠 수 있다.
- ORM 레이어의 락과 데이터베이스 레이어의 락 중 어떤 것이 나은지는 애플리케이션의 특정 요구 사항에 따라 다를 것 같다.
찾은 해결방안 적용
ORM lock은 애플리케이션 레밸에서 구현이 되고, 데이터의 lock을 얻고, 해제 하는 행위를 ORM에 의존을 해야한다.
그리고 ORM lock은 데이터베이스 lock과 유사한 기능을 제공하지만, 데이터를 먼저 데이터베이스에서 검색한 다음 잠금을 획득해야 하기 때문에 성능이나 신뢰성이 부족하다.
이와 같은 추가적인 프로세스는 overhead를 추가하고 race condition을 야기하기 때문에 ORM lock은 오버부킹을 해결하는데 적합하지 않다.
결과
결국은 exclusive lock을 사용하면 된다.
그러므로
@Lock(value = LockModeType.PESSIMISTIC_WRITE)
을 사용해주면 되겠다.