프로젝트 도중 동시성 문제가 발생했을 때
syncronized와 수동적 Transaction 제어를
통해서 문제를 해결하였다..(해결한건가?)
여기서의 문제점은 동일한 JVM에서 실행 중인 스레드들 사이에서만 동기화 문제가 해결 된다는 점이다.

이러한 구성에서는 전 포스팅에서 말한 해결방법을 가지고 문제를 해결 할 수 있다!!
하지만!

이렇게 여러개의 서버로 확장이 일어났을 때는
동기화 문제가 해결되지 않는다..
그러면 애플리케이션 레벨이 아닌
DB 레벨에서 제어를 하는것이 더 일관성있고
동기화 문제를 해결하는데 있어서
더 좋은 선택인거 같다!!
데이터베이스 DB LOCK
여러 DBMS마다 락의 종류와 분류하는 방식이 다른긴 하겠지만
내가 사용하는 MySQL 의 대표적인 락에 대해서 알아보도록 하자
일단 락을 구분하는 방식이 여러 가지가 있지만 (대상에 대한 분류, 동작 방식에 따른 분류)
이 포스팅에서는 동작 방식에 대해서 분류를 한다.

비관적 락(Pessimistic Lock) vs 낙관적 락(Optimistic Lock)
낙관적인 락
- 충돌이 발생하지 자주 발생하지 않는다고 가정한다.
- Version Column을 추가
- DB에서 처음 읽어온 Version을 기억
- UPDATE 할 때 현재 DB의 Version과 다르다면 롤백한다.
비관적인 락
- 충돌이 자주 발생할 것이라고 가정
- TABLE or ROW에 LOCK 을 걸고 트랜잭션 작업을 진행
- 다른 트랜잭션은 LOCK 흭득까지 대기
- 작업 완료시 LOCK 해제
차이점이 보이는가?
그림 으로 설명하면 더 자세하게 이해할 수 있지만 맨 밑에 더 좋은 참고영상이 있어서
올려놓았다 ㅋㅎ
가장 큰 차이점
LOCK의 사용 유무?
충돌이 자주 일어나는가?
위의 두개를 고려하여 기술에 대한 선택을 하면 좋을 듯 하다.
충돌이 자주 일어난다 생각하면 무조건 비관적 락을 선택하면 좋은거 아닌가?
생각해보자 충돌이 자주일어나는 만큼 상대적으로 느리게 동작한다
낙관적 락은 락에 의해 동작하지 않기 때문에
락 오버헤드 발생 가능성이 적다 그렇기 때문에
동시성 문제가 잦지 않다면
낙관적 락을 선택하는 것이 더 좋은 기술적 선택이라 생각
내 프로젝트의 좋아요 기능에 관해서는 충돌이 잦다고 가정하고 비관적 락을 적용해보겠다!!
비관적 락은 보통 두개의 락으로 구분되어진다.
공유 락과 배타 락인데
공유 락은 다른 트랜잭션이 데이터에 대해 읽기를 할 수 있지만 수정을 할 수 없도록 막는다.
SELECT * FROM table_name WHERE id = 1 FOR SHARE;
배타 락은 다른 트랜잭션이 데이터를 읽고 쓰는 거에 대해 잠금을 걸어서 해당 테이터를 읽거나 수정 모두 할 수 없도록 만든다.
SELECT * FROM table_name WHERE id = 1 FOR UPDATE;
자 그럼 전 포스팅에서 봤었던 좋아요 기능에 대해서 살펴보자

JPA 에서 @Lock 을 통해서 베타적 락을 간편하게 이용할 수 있다.


for update 가 붙는것을 확인할 수 있다 행을 수정하거나 삭제하지 못하도록 베타 잠금을 설정


성능적인 부분의 이슈
레코드 자체에 락을 건다는 건 해당 레코드에 접근하는 다른 요청들은 대기해야 한다
그렇다면 성능적으로 개선하기 위한 다른 방법은 무엇이 있는가?
다음 포스팅에서 알아보자!!
https://www.youtube.com/watch?v=era8W7q3CeQ
'프로젝트' 카테고리의 다른 글
| Docker 도입하여 개발 환경을 셋팅해보자 (0) | 2025.12.22 |
|---|---|
| 안전한 파일 업로드에 대한 처리란 무엇일까? chapter 2 (0) | 2024.11.27 |
| 좋아요 버튼의 숨겨진 딜레마: @Transactional과 synchronized가 함께 풀지 못한 동시성 이슈 (0) | 2024.11.26 |
| 동적 쿼리와 배치 사이즈 최적화로 1+N 문제 해결 및 성능 개선 (0) | 2024.11.23 |
| Offset 페이징에서 효율적인 대댓글 처리 방법 (0) | 2024.11.23 |