테이블의 row에 접근 시 lock을 걸고 다른 lock이 걸려 있지 않는 경우에만 수정이 가능하도록 설정
수정할 때 내가 먼저 이 값을 수정했다고 명시하여 다른 사람이 동일한 조건으로 값을 수정할 수 없게 하는 것
낙관적 락(Optimistic Lock)
이론
수정할 때 내가 이 값을 수정했다고 명시하여 다른 사람이 동일한 조건으로 값을 수정할 수 없게 하는 것 (주로 versioning)
DB에서 제공하는 것이 아닌 어플리케이션 레벨에서 잡아주는 Lock
애시당초 버전을 동시에 select query에 사용하기 때문에 해당 row가 update된 경우 찾을 수 없음
hashcode와 timestamp를 이용하기도 한다
비관적 락(Pessimistic Lock)
이론
선전 잠금
트랜잭션끼리의 충돌을 발생한다 가정하고 미리 락을 거는 것
DB에서 제공하는 락 기능 사용
Repeatable Read, Serializable 급의 격리 수준 제공
사용법
작동원리
쿼리를 다음(select for update)과 같이 나가게 하여 업데이트 용으로 해당 데이터를 찾는 것이니 다른 곳에서 건들 수 없도록 하라는 것
Hibernate: select home0_.idx as idx1_0_, home0_.address as address2_0_, home0_.name as name3_0_, home0_.price as price4_0_ from home home0_ where home0_.name=? for update
종류
LockModeType.PESSIMISTIC_WRITE
일반적인 비관적 락으로, 다른 트랜잭션에서 읽지도 쓰지도 못함
베타적 잠금
LockModeType.PESSIMISTIC_READ
반복 읽기만 하고 수정하지 않는 용도로 락을 걸 때 사용
다른 트랜잭션에서 읽기는 가능함
LockModeType.PESSIMISTIC_FORCE_INCREMENT
버저닝을 위한 비관적 락
롤백
2개 이상의 row를 업데이트하다 1번째 row를 완료하고 2번째에서 충돌이 발생한 경우, 롤백이 발생한다
낙관적 락의 경우
충돌이 발생하여 수정을 못한 부분에 대해서는 롤백에 대한 책임을 어플리케이션 단으로 주어 어플리케이션에서 수동으로 롤백해주어야 한다
비관적 락의 경우
하나의 트랜잭션에 두 row를 수정하는 쿼리가 묶여있기 때문에 모두 롤백된다
사용하는 경우
낙관적 락은 트랜잭션을 필요로 하지 않아 성능적 우수
트랜잭션을 타지 않기 때문에 충돌이 많이 일어나지 않을 것이라고 보여지는 곳에서 좋은 성능을 기대
그러나 롤백이 되는 경우, 충돌이 났다고하면 이를 개발자가 수동으로 처리해주어야 하기 때문에 공수가 필요하고 버그가 발생할 수 있다