두 트랜잭션에서 데이터 변경 → 최종적으로 한 트랜잭션의 결과만 남는 것
⇒ 해결: 마지막 커밋만 인정 / 최초의 커밋만 인정 / 충돌하는 갱신 내용 병합
⇒ JPA에서는 비관적 락/낙관적 락 매커니즘 제공
트랜잭션의 충돌이 발생한다고 가정
트랜잭션이 시작될 때 데이터베이스에 락 → 다른 트랜잭션 접근 X
SELECT
쿼리는 Lock 사용 X
SELECT … FOR SHARE
등의 일부 쿼리는 각 Row에 Shared Lock 검SELECT … FOR UPDATE
, UPDATE
, DELETE
등의 수정 쿼리들이 실행될 때 Row에 걸림커스텀 메서드에 @Lock
어노테이션 붙이고 Lock 어노테이션의 설정 값인 value에 설정하고자 하는 LockModeType
을 지정해주면 됨
PESSIMISTIC_READ
, PESSIMISTIC_WRITE
, PESSIMISTIC_FORCE_INCREMENT
public interface TransactionRepository extends JpaRepository<Transaction, Long> {
@Lock(value -
}
대부분의 트랜잭션은 충돌이 발생하지 않는다고 낙관적으로 가정
데이터베이스가 제공하는 락 X 애플리케이션 레벨에서 락 구현(↔ 비관적 락)
⇒ 트랜잭션 커밋 전까지 충돌 알 수 없음
@Version
→ 해당 엔티티 테이블 읽는 각 트랜잭션은 업데이트 수행하기 전 버전의 속성 확인
IF. 업데이트 하기 이전에 버전 값 변경 → OptimisticLockException
발생