락 제어
트랜잭션 격리수준 4가지
- READ UNCOMMITTED = DIRTY READ, NON-REPEATABLE READ, PHANTOM READ 발생
- READ COMMITTED = NON-REPEATABLE READ, PHANTOM READ 발생
- REPEATABLE READ = PHANTOM READ 발생
- SERIALIZABLE
DIRTY_READ : 트랜잭션 1이 수정중이고, 커밋하지 않은 데이터를 트랙잭션2가 조회 가능한 것
NON-REPEATABLE READ: 트랜잭션 1이 A를 조회하고, 다른작업을 진행중에 트랜잭션 2가 A를 수정하여, 트랜잭션1이 다른작업 후 다시 A를 조회했을때 다른 테이터가 조회되는 것.
PHANTOM_READ: 트랜잭션 1이 10살 이하 회원을 조회 하였을때 카운트가 10, 트랜잭션 2가 10살 이하 회원 한명 추가, 트랜잭션 1이 다시 10살 이하 회원 조회시 데이터가 한건 추가조회 되는 것.
낙관적 락과 비관적 락
낙관적 락: 트랜잭션 대부분이 충돌하지 않을 것이라고 낙관적으로 가정하는 방법
비관적 락: 트랜잭션 대부분이 충돌 할 것이라고 가정하여 우선 락을 걸고 보는 방법
jpa의 @version
- Entity를 수정할때마다 버전이 1씩 증가한다.
- Entity 조회시점 version 과 수정시점 version 이 다르면 예외가 발생한다.
@Entity
public class Board {
....
@Version
private Integer version;
}
JPA 락 사용
JPA에서 락은 해당 위치들에 적용 가능하다.
EntityManager.lock(), find(), refresh()
Query.setLockMode()
@NamedQuery
ex)
em.find(Board.class, id, LockMode.OPTIMISTIC) //조회하면서 락
em.finc(Board.class, id);
em.lock(board, LockModeType.OPTIMISTIC) // 필요한 시점에 락
락 모드 종류
OPTIMISTIC - 낙관적 락
- 락 모드 없이(NONE) @Version 만 사용하면 수정할 때만 버전을 체크 하지만, OPTIMISTIC은 조회 할때에도 버전을 체크한다.
- DIRTY READ, NON-REPEATABLE READ 방지
OPTIMISTIC_FORCE_INCREMENT - 낙관적락 + 버전정보 강제 증가
- 엔티티를 수정할때 1번, 수정하지 않아도 커밋이 호출될때 1번 버전이 업데이트 된다.
- 게시글과 첨부파일이 1:N관계일때, 게시글은 변경되지 않고 첨부파일만 추가되거나 변경 되더라도 게시글에 버전처리를 하고 싶을때 사용된다.
PESSIMISTIC_READ - 비관적락, 읽기 락 사용
- 데이터를 반복 읽기만 하고 수정하지 않는 용도로 사용.(잘 사용하지 않는다.)
PESSIMISTIC_WRITE - 비관적 락, 쓰기 락 사용
- 데이터베이스 select for update 를 사용해 락을 건다.
- NON-REPEATABLE READ 방지한다 (select를 하며 해당 로우에 락이 걸려 다른 트랜잭션이 수정불가)
PESSIMISTIC_FORCE_INCREMENT - 비관적 락 + 버전정보 강제 증가
- 비관적 락 + 버전정보 강제 증가가 함께 사용된다.
NONE - 락을 걸지 않음
READ - 레거시 기능, OPTIMISTIC 과 동일
WRITE - 레거시 기능, OPTIMISTIC_FORCE_INCREMENT 와 동일
'JAVA' 카테고리의 다른 글
Jackson 어노테이션 정리 (0) | 2021.04.30 |
---|---|
JPA 캐시 (0) | 2021.04.28 |
JPA 성능 최적화 (0) | 2021.04.28 |
JPA 엔티티 그래프 (0) | 2021.04.28 |
JPA 엔티티 생명주기에 리스너 등록 (0) | 2021.04.28 |