처음에는 낙관적 락, 비관적 락, 분산 락을 고려했다. 그러나 이 프로젝트는 서버가 분산되지 않았고, DB 또한 분산 DB가 아니기 때문에 분산 락은 배제했다.
낙관적 락은 대부분의 트랜잭션이 충돌이 발생하지 않을 것
이라고 낙관적으로 가정하는 방법이다.
데이터베이스가 제공하는 락 기능을 사용하지 않고, 엔티티의 version
컬럼을 통해 동시성을 제어한다.
낙관적 락 도중 충돌이 발생하면 개발자가 수동으로 롤백처리
를 해줘야한다.
엔티티를 수정할 때(update 쿼리가 날아갈 때) 버전이 증가한다.
엔티티를 조회한 시점의 버전과 수정한 시점의 버전이 일치하지 않으면 예외가 발생한다. (ObjectOptimisticLockingFailureException)
@Version
으로 추가한 버전 관리 필드는 JPA가 직접 관리하므로 임의로 수정해서는 안된다.
임베디드 타입과 값 타입 컬렉션은 실제 DB에서는 다른 테이블이지만, JPA에서는 논리적인 개념해당 엔티티에 속한 값이므로 수정하면 엔티티의 버전이 증가
벌크 연산
의 경우 버전을 무시하므로 버전 필드를 증가하는 부분을 추가
해야한다.
update Recruitment p set p.applicant_count = p.applicant_count + 1, p.version = p.version + 1