티스토리 뷰

Study/JPA

낙관적 락, 비관적 락

dev ms 2019. 4. 10. 23:36
반응형

동시성 프로그래밍에서 고려되야 할 사항으로 트랜젝션 처리가 있는데,
트랜젝션 처리를 어떤 방향으로 하느냐에 따라서 성능이 좌우된다.

낙관적 락은 트랜젝션 대부분 충돌이 발생하지 않는다고 가정하는 방법이다.
쉽게 말해 애플리케이션이 제공하는 락이다.
낙관적 락은 트랜잭션을 커밋하기 전까지는 트랜잭션의 충돌을 알 수 없다는 특징이 있다.

비관적 락은 트랜잭션의 충돌이 발생한다고 가정하고 우선 락을 걸고 보는 방법이다.
데이터 베이스가 제공하는 락 기능을 사용한다. 대표적으로 select for update 구문이 있다.

추가로 데이터베이스 트랜잭션 범위를 넘어서는 문제도 있다.

예를들어 사용자 A와 B가 동시에 제목이 같은 공지사항을 수정한다고 생각해보자.
둘이 동시에 수정화면을 열어서 내용을 수정하는 중에 사용자 A가 먼저 수정완료 버튼을 눌렀다.

잠시 후에 사용자 B가 수정완료 버튼을 눌렀다.
결과적으로 먼저 완료한 사용자 A의 수정사항은 사라지고 나중에 완료한 사용자 B의 수정사항만 남게 된다.
이것을 두 번의 갱신 분실 문제 second lost updates problem라 한다.

두 번의 갱신 분실 문제는 데이터베이스 트랜잭션이 범위를 넘어선다. 따라서 트랜잭션만으로는 문제 해결이 발구낭하다.

이때 3가지 선택 방법이 있다.

마지막 커밋 인정하기.
- 사용자 A의 내용은 무시하고 마지막에 커밋한 사용자 B의 내용만 인정.
최초 커밋만 인정하기.
- 사용자 A가 이미 수정을 완료했으므로 사용자 B가 수정을 완료할 때 오류가 발생한다.
충돌하는 갱신 내용 병합하기.
 - 사용자 A와 사용자 B의 수정사항을 병합한다.

기본은 마지막 커밋만 인정하기이다.
하지만 상황에 따라 최초 커밋만 인정하기가 더 합리적일 수 있다.

반응형