Oracle Database를 사용하는 주택금융공사 차세대 프로젝트 때 일이다.
주택금융공사 사내 프로그램을 개발중이었고,
예산 파트를 맡았었고... 예산 출납이 빈번히 일어났었다.
(각종 경비, 급여, 추경, 예산 배정 그리고 이를 따라가는 지옥의 차변대변)
빈번히 일어나는 예산 변화만큼 동시성 이슈도 자주 발생했는데
이 때 사용한게 비관적 락이다.
즉, 많은 분들이 아시겠지만 FOR UPDATE 바로 그 것이다.
PK로 조회한 행을 Lock걸고 다른 트랜잭션이 권한을 가져가지 못하도록 한다.
예를 들자면 출입구가 많은 놀이동산이 비상이 걸려서 출입구를 하나로 만들고 한 명씩 차례대로 출입하게 만드는 것(?)과 같다.
장점은 간단하고 명확하게 데이터 정합성을 맞추는 것이지만
단점은 성능 이슈가 생길 수 있다고 한다(는 아직 이로 인해 발생하는 성능 이슈를 겪어본 적은 없음...).
MySQL에서 사용할 때는 Autocommit이 풀려있는 상태여야하고 락 해제 시 반드시 Commit을 해줘야 한다.
우리 회사는 이번 동시성 이슈를 비관적 락을 활용하여 처리하였으나, 이를 위한 SP를 작성하였고
글 최하단 참고
이번 강의를 통해 JPA에서는 이를 얼마나 간단하게 처리하는지 알 수 있었다(우리 회사도 JPA를 사용하면 안 되나...? 는 나한테 권한이 없다. 공부나 열심히 하자).
JPA에서는 어노테이션 하나로 복잡한 로직 작성이 끝난다.
@Lock(value = LockModeType.PESSIMISTIC_WRITE)
@Query("select s from Stock s where s.id = :id")
이를 활용하면 Lock을 위한 dummy table을 만들어두고 update와 commit 사이에 필요한 로직을 넣어서 서버로 들어온 요청들을 줄세울 수도 있다.