728x90
JPA를 사용할때는 Transaction에 대한 격리 수준이 존재합니다. 여기서 @Transactional 어노테이션에 대해서 다루었었죠. 어노테이션의 기본값은 DB의 격리정책과 동일하게 가는 것으로 돼있는데, 대부분의 데이터베이스들은 ACID 원칙에서 격리성(Isolation)을 만족시키기 위해 READ COMMITED 수준을 사용합니다.
트랜잭션의 ACID 특성
- 원자성 (Atomicity): 부분적으로만 실행되거나 중단되지않는 것을 보장
- 일관성 (Consistency): 트랜잭션이 완료되면 일관적인 DB상태를 유지
- 격리성 (Isolation): 트랜잭션 수행시 다른 트랜잭션이 끼어들지 못하도록 보장
- 지속성(Durabuility): 성공적으로 수행된 트랜잭션은 영원히 반영
격리 수준에는 대표적으로 다음의 종류가 있습니다
- READ UNCOMMITEED: 커밋되지 않은 데이터 읽을 수 있음 Dirty Read(커밋되지 않은 데이터 읽기) , Dirty Write (커밋되지 않은 정보 덮어쓰기) 가능 (거의 사용안함)
- READ COMMITED: 커밋된 데이터만 읽을 수 있음, Read Skew(읽는동안 데이터 변경) 발생 가능
- REPEATABLE READ: 트랜잭션 동안 같은 데이터를 읽게 보장, Lost Update(변경사항 유실) 발생 가능
- SERIALIZABLE: 모든 트랜잭션을 순서대로 실행
격리 수준은 종류별로 높고 낮음이 존재하는데요, READ COMMITED 이상의 격리수준이 필요할때 비관적 락, 낙관적 락을 사용할 수 있습니다.
비관적 락 (Pessimistic Lock)
- 트랜잭션이 충돌한다고 미리 가정하고 우선 락을 겁니다. (비관적으로 생각하는거죠!)
- DB가 제공하는 락 기능을 사용합니다
- 데이터 수정시 즉시 트랜잭션 충돌을 알 수 있습니다
낙관적 락 (Optimistic Lock)
- 트랜잭션 충돌이 발생하지 않는다고 가정합니다.
- DB가 제공하는 락을 사용하지 않고 JPA 가 제공하는 version 관리 기능을 사용합니다.
- 트랜잭션이 커밋되기 전까지는 트랜잭션의 충돌을 알 수 없습니다.
낙관적 락의 특징은 아래처럼 Version 관리 기능을 사용해야한다는 것인데요
@Entity
public class Member {
@Id
private Long id;
private String name;
@Version // 버전 어노테이션 명시
private Integer version;
{
예를들어 트랜잭션1이 데이터를 조회해서 수정중인데, 그 사이 트랜잭션2가 데이터를 수정했고 데이터의 version은 상승했습니다. 이후 트랜잭션1 이 수정작업을 끝내고 커밋을하면 버전의 불일치로 (더 낮은 버전으로 커밋) 트랜잭션1의 작업은 오류가 나게 됩니다.
위 그림처럼 버전관리를 통해 트랜잭션이 관리됩니다.
출처:
- [JPA] 비관적 락 , 낙관적 락
- [JPA] 낙관적 락이란?
728x90
'Spring' 카테고리의 다른 글
[Maven] Maven이란? (feat. Maven lifecycle) (1) | 2023.04.09 |
---|---|
[Spring] @Transactional 어노테이션 동작방식 (0) | 2023.02.21 |
[Spring] Spring AOP 프록시 - JDK Proxy(JDK Dynamic Proxy), CGLib (0) | 2022.10.30 |
[JPA] @OneToMany 단방향을 사용하면 안되는 이유 (0) | 2022.10.27 |
[JPA] @ManyToOne, @OneToMany 뭘 써야할까? (0) | 2022.10.13 |