Pessimistic Lock(비관적 락) vs. Optimistic Lock(낙관적 락)
두 번의 갱신 분실 문제(Second lost updates problem)
두 트랜잭션에서 데이터 변경 → 최종적으로 한 트랜잭션의 결과만 남는 것
⇒ 해결: 마지막 커밋만 인정 / 최초의 커밋만 인정 / 충돌하는 갱신 내용 병합
⇒ JPA에서는 비관적 락/낙관적 락 매커니즘 제공
Pessimistic
트랜잭션의 충돌이 발생한다고 가정
트랜잭션이 시작될 때 데이터베이스에 락 → 다른 트랜잭션 접근 X
•
Shared Lock(공유 락, S Lock)
◦
특정 Row 읽을(Read) 때 사용
◦
여러 트랜잭션이 동시에 한 Row에 S Lock 걸 수 있음
▪
하나의 Row를 여러 트랜잭션이 동시에 읽을 수 있음
◦
S Lock이 설정된 Row에는 X Lock 사용 X
◦
InnoDB에서 일반적인 SELECT 쿼리는 Lock 사용 X
▪
But, SELECT … FOR SHARE 등의 일부 쿼리는 각 Row에 Shared Lock 검
•
Exclusive Lock(배타 락, X Lock)
◦
특정 Row를 변경(Write)할 때 사용
◦
X Lock이 설정된 Row에는 다른 트랜잭션을 읽기 위해 S Lock 걸거나, 쓰기 위해 X Lock 걸 수 X
▪
쓰기 작업을 하고 있는 Row에는 모든 접근 불가
◦
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 -
}
Java
복사
Optimistic
대부분의 트랜잭션은 충돌이 발생하지 않는다고 낙관적으로 가정
데이터베이스가 제공하는 락 X 애플리케이션 레벨에서 락 구현( 비관적 락)
⇒ 트랜잭션 커밋 전까지 충돌 알 수 없음
@Version → 해당 엔티티 테이블 읽는 각 트랜잭션은 업데이트 수행하기 전 버전의 속성 확인
IF. 업데이트 하기 이전에 버전 값 변경 → OptimisticLockException 발생
•
각 엔티티 클래스에는 한 개의 버전 필드만 있어야 함
•
여러 테이블에 매핑된 엔티티의 기본 테이블에 배치해야 함
•
버전 유형: int, Integer, long, Long, short, Short, java.sql.Timestamp
•
엔티티 ~> 버전이 어떠한지 필드 탐색 O 직접 수정 X
◦
벌크 연산시 JPA가 관리 X → 직접 +1
@Entity
@NoArgsConstructor
@AllArgsConstructor
public class Account {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Version
private int version;
...
}
Java
복사
비관적 락
•
데이터베이스 레벨의 락 → 데이터의 무결성 But, 성능상 손해
•
충돌 ↑ → 잦은 롤백으로 인한 효율성 문제 발생하는 것이 예상되는 시나리오에 사용
낙관적 락
•
실제로 데이터 충돌 자주 일어나지 않을 것이라고 예상되는 시나리오에 사용
•
But, 추가적인 오류 처리 + 동시 접근 ↑ → 오류 처리를 위해 더 많은 리소스 소모
그래서 우리 프로젝트는?
특징 | 분산 락 | 비관적 락 |
적용 범위 | 분산 환경에서 여러 노드에 걸쳐 동작 | 단일 데이터베이스 내에서만 동작 |
성능 | 네트워크 호출 비용 | DB 트랜잭션 처리 속도에 의존 |
확장성 | 분산 환경에서도 적합 | 확장성 제한(단일 DB 노드 중심) |
일관성 보장 | 네트워크 상태 → 정합성 위험 | 강력한 일관성 |
데드락 가능성 | 낮음(TTL 설정으로 방지 가능) | 높음(교착 상태 발생 가능) |
⇒ 데이터베이스 분산 → 분산 락