-
JPA 동시성 문제 해결하기 (트랜잭션과 락)프로젝트/WebRTC 화상통화 프로젝트 2022. 8. 9. 00:01
동시성 문제란?
두개 이상의 세션이 공통된 자원에 대해서 읽고 쓰는 작업을 할 때 발생할 수 있는 문제입니다.
기본적으로 동시성 문제는 완전한 해결이 있는 것이 아닌 타협입니다.
성능을 포기하고 정확성을 높이느냐 vs 정확성을 타협하고 성능을 높이느냐
이러한 점을 명확하게 보여주는것이 바로 트랜잭션의 격리 단게입니다.
Read Uncommited, Read Commited, Repeatable read, Serializable
일반적으로 주로 사용되는 DB는 주로 Rad Commited에 해당하는 격리수준을 가지고 있습니다.
하지만 JPA를 사용할 경우 영속성 컨텍스트에 캐시해놓기 때문에 Repeatable read 수준과 동일하게 동작하게 됩니다.
JPA 에서는 영속성 컨텍스트에 캐시하기 때문에 "읽관성 없는 읽기"는 없습니다.
주로 해결해야 하는 문제는 "갱신 손실"입니다.
더 늦게 시작한 세션2에 의해 세션1의 변경사항이 무시되는 현상을 "손실되는 업데이트"라고 합니다.
우리가 직접 조성하는 비즈니스 시스템에서 중요하게 고려되어야 하는 문제입니다.
"집중" 프로젝트는 팀별로 단 하나의 운동방을 가질 수 있다는 제약조건이 존재합니다.
하지만 만약 위의 예시처럼 세션1이 방을 개설하는 동안 세션2가 방을 개설하는 경우에는 동시에 방이 2개가 생성되며 DB에는 세션2의 방정보만 남게 됩니다.
해결법
Optimistic Lock(낙관적 잠금)
세션1이 데이터를 읽어 왔더라도 다른 세션인 세션2도 해당 데이터에 자유롭게 접근할 수 있습니다.
하지만 세션2가 Write를 할 때 세션2의 데이터가 읽은 데이터와 달라졌다면 저장할 수 없습니다.
JPA에서는 @Version 어노테이션으로 공통 리소스가 업데이트 되었느지 버전을 관리합니다.
Pessimistic Lock(비관적 잠금)
데이터베이스의 lock 기능을 사용하여 엔티티를 영속 상태로 올릴 때부터 다른 세션에서 조회자체를 막아버립니다.
mysql에서 select for update와 같은 방식의 쿼리로 lock을 요청합니다.
활동성이 저하되지만 정확성과 세션의 성공은 보장됩니다.
Pessimistic Locking vs Optimistic Locking
Pessimistic Locking
비관적 잠금은 세션이 실패할 확률은 줄여주지만, 여러 세션의 “활동성” 은 높여주지는 못한다.
정확성이 중요한 서비스에 적합합니다.
Optimistic Locking
활동성은 높일 수 있지만, 업데이트에 실패할 수 있다.
잘 진행되고 있던 프로세스가 변경 사항을 저장하려고 할 때 까지 프로세스의 성패를 예측할 수 없다.
쓰기보다 읽기 작업이 많은 서비스에 적합하다.
프로세스에서 Rollback을 마지막 단계에 알 수 있어서 중간에 외부 시스템 API를 사용하는 과정이 있다면 사용하기 어렵습니다.
출처
'프로젝트 > WebRTC 화상통화 프로젝트' 카테고리의 다른 글
Rest API로 Apple 로그인을 구현 (0) 2023.06.06 Sign In with Apple REST API 문서 정리 (1) 2023.05.16 nginx에 SSL 인증서 적용하기 (0) 2022.08.08 Jenkins로 Gitlab CI/CD 구축하기(Spring + MySQL + JenKins + Redis + Nginx) (0) 2022.08.06 letsencrypt 인증서 발급하고 OpenVidu에 적용하기 (0) 2022.08.05