티스토리 뷰

Second Lost Updates Problem ( 두 번의 갱신 분실 문제 )

2개의 트랜잭션에서 동일한 데이터를 변경 하려 할 경우 마지막으로 커밋된 내용이 적용되고 먼저 커밋된 내용이 무시되는 문제이다.

예를 들어 A,B라는 사람이 있는데 동시에 게시글의 제목을 변경하려고 한다.

A라는 사람은 제목을 'TITLE1'이라고 변경하고, B라는 사람은 제목을 'TITLE2'라고 변경하고 저장을 누른다.

이럴 경우, A라는 사람이 먼저 저장을 누른 후 B라는 사람이 저장을 누르면 게시글의 제목은 최종적으로 'TITLE2'로 저장 될 것이다. 이럴 경우, A라는 사람은 제목이 'TITLE1'로 변경되었겠지..라고 생각하겠지만, 예상치 못한 결과가 나올 수 있는 것이다.

이럴 경우, JPA에서 사용 할 수 있는 방법을 제시한다.

@Version 어노테이션을 사용하는것이다. 이 방법은 '낙관적 락'을 사용하는 것인데 사용법에 대해서는 https://www.baeldung.com/jpa-optimistic-locking 여기에 잘 설명되어있다.

Second Lost Updates Problem 방지가 필요한 Table에 version용으로 사용할 컬럼을 하나 추가해 두고, select할 때의 version과 update 할 때의 version 일치 여부를 체크 하는 것이다.

update
    board 
set
    title=?,
    version=? 
where
    id=? 
    and version=?

이런 식으로 where 조건에 version에 대한 조건을 추가해서 쿼리를 날리며 version도 함께 version+1로 업데이트 해주게 되는데, 다른 트랜잭션에 의해 row가 변경되었다면, update된 row가 없게 되는 것이다. 이럴 경우 JPA에서는 org.springframework.orm.ObjectOptimisticLockingFailureException을 발생시키며 Second Lost Updates Problem을 방지하고 최초 커밋만 인정하게 된다.

댓글