Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
Tags
- 우아한테크코스
- tomcat설정
- 트랜잭션성질
- mysqld.sock
- 스프링트랜잭션
- 자바비동기
- 트랜잭션
- 트랜잭션속성
- 데이터베이스락
- 코틀린
- 객체지향생활체조
- 백준
- 테코톡
- 코틀린기초
- GithubOAuth
- java
- DynamicWebProject
- S2139
- kotlin
- 리버스프록시
- 레벨로그
- jsp프로젝트
- ObjectCalisthenics
- subprocess에러
- 무중단배포
- Google Place Photo API
- KotlinInAction
- 코틀린뽀개기
- 알고리즘
- servlet프로젝트
Archives
- Today
- Total
초이로그
데이터베이스 락 본문
요약
Optimistic Lock | Pessimistic Lock | |
정의 | 충돌이 없을 것이라 예상 | 충돌을 예상하고 미리 락을 건다 |
사용방법 | JPA를 사용하면 @Version 동작원리가 단순해서 만들기 쉬움 |
Mode 설정 및 쿼리에 직접 사용 DB 단에서 설정가능 |
별명 | 낙관적인 락 / 비선점적인 락 | 비관적인 락 / 선점적인 락 |
장점 | 데드락 가능성이 적으며 성능의 이점 | 충돌에 대한 오버헤드가 줄어든다 무결성을 지키기 용이하다 |
단점 | 충돌이 발생하면 오버헤드 발생 | 충돌이 없으면 오버헤드 발생 |
정의
데이터베이스의 일관성과 무결성을 유지하기 위해 트랜잭션의 순차적 진행을 보장할 수 있는 직렬화 장치
데이터의 일관성을 지키기 위해 LOCK(잠금)을 걸고 이를 관리하는 것이 Locking
여러 개의 트랜재션에서 동시에 접근하여 수정하려고 할 때, 일관성이 깨질 수 있다. 잠금을 사용하자.
예) 두 명이 A에게 3,000원씩 입금했지만 총 입금된 금액은 3,000원
종류
Optimistic Lock
- 낙관적 - 기본적으로 데이터 갱신 시 충돌이 발생하지 않을 것이라고 낙관적으로 보는 것
- 비섬전적 - 데이터 갱신 시 충돌이 발생하지 않을 것이라고 예상하기 때문에 우선적으로 락을 걸지 않음
- Version을 사용해 관리
- 어플리케이션 레이어에서 거는 락(DB에서 관리하는 것은 없음)
- 데드락 가능성이 적고 성능의 이점
- 충돌 방지용
- 커밋 시점에 충돌이 발생하면 이전에 실행된 것이 모두 롤백(오버헤드)
@Entity
public class Student {
@Id
private Long id;
@Version // 버전 애너테이션을 통해 자동으로 관리된다
private Integer version;
}
@Test(expected = OptimisticLockException.class)
void test() {
try {
EntityManager em = getEntityManagerWithOpenTransaction();
Student student = em.findStudent(Student.class, 1L); // Version 1
EntityManager em2 = getEntityManagerWithOpenTransaction();
Student student2 = em2.findStudent(Student.class, 1L); // Version 2
student2.setName("페퍼");
em2.persist(student2);
em2.getTransaction()
.commit(); // Version2
em2.close();
student1.setName("그린론");
em.getTransaction()
.commit(); // Version 1,2의 충돌
em.close();
} catch (Exception e) {
// ...
}
}
Pessimistic Lock
- 비관적인 - 기본적으로 데이터 갱신 시 충돌이 발생할 것이라고 비관적으로 보고 미리 잠금을 거는 것
- 선점적인 - 데이터 갱신 시 충돌이 발생할 것이라고 예상하므로 우선적으로 락을 건다(조회할 때부터 건다)
- 조회할 때 DB에 락을 건다
- 데이터베이스 락
- 무결성의 장점
- 락을 실제로 걸기 때문에 데드락의 위험성
- 충돌이 없으면 락 자체가 비용이라 오버헤드 발생
- 다양한 추가 설정
- Shared Lock: 다른 사용자가 동시에 읽을 수는 있지만, Update Delete를 방지함. S Lock이 걸린 row에 S Lock은 걸 수 있지만 X Lock은 걸 수 없다.
- Exclusive Lock(X Lock): 다른 사용자가 읽기, 수정, 삭제 모두를 불가능하게 함. X Lock이 걸리면 다른 트랜잭션은 S Lock, X Lock 둘 다 걸 수 없다.
- Record Lock: MySQL의 InnoDB에서 제공하는 Lock. 락은 동일한 조건의 record(=row)에 걸릴 수 있는데 innoDB에서는 다른 rdbms와 달리 테이블 레코드가 아닌 인덱스 레코드에 락을 건다. (X Lock, S Lock 모두 인덱스 레코드에 걸린다) 인덱스가 없는 경우 테이블 내 숨겨져있는 clustered index를 사용하여 record 잠금
- Gap Lock: 인덱스 레코드의 gap(인덱스 레코드에서 없는 부분)에 걸리는 Lock. 조건에 해당하는 새로운 row가 추가되는 것을 방지
- 이 외에도 Next Key Lock, Table Lock 등이 존재
@Test
void test() {
try {
EntityManager em = getEntityManagerWithOpenTransaction();
Student student = em.findStudent(Student.class, 1L);
em.refresh(student, LockType.PESSIMISTIC_WITH); // Exclusive Lock
EntityManager em2 = getEntityManagerWithOpenTransaction();
Student student2 = em2.findStudent(Student.class, 1L); // 조회에서 예외 발생
// 이후 로직 모두 수행 X
} catch (Exception e) {
// ...
}
}
- 버전을 사용할 수는 있지만 잘 사용하지 않음
Optimistic vs Pessimistic
언제 무엇을 사용할까?
락은 비용이 크기 때문에 어떤 상황인가가 중요하다.
- 충돌이 자주 발생하는 상황인가? ➡️ Pessimistic
- 읽기와 수정하기의 비율은 어디에 가까운가?
- 읽기 비율이 크다 ➡️ Optimistic 또는 락을 걸지 않는다
- 수정 비율이 크다면 ➡️ Pessimistic
- 요즘에는 오버헤드가 많이 줄어들어서 수정하기도 Optimistic도 사용한다고 함
- 일반적인 웹 애플리케이션은 읽기 요청이 대부분이라 Optimistic 락 주로 사용
DB에서 발생하는 DeadLock
상황
트랜잭션 1은 트랜잭션 2에서 Lock이 걸린 자원을 원하고, 트랜잭션 2는 1에서 Lock이 걸린 자원을 원하는 경우 발생
해결 방법
- deadlock detection 또는 lock wait timeout (mysql, oracle 기준)
- Deadelock detection이 활성화 되어있으면 rollback할 작은 트랜잭션 선택
- 트랜잭션 크기는 Insert, update, delete 된 행 수에 의해 결정. 하지만 oracle에서는 반드시 그렇지 않음. 벤더 사마다 다르다
- 활성화 되어있지 않으면 설정된 lock wait timeout으로 해결
추가로 공부하면 좋을 내용
- 도메인에 대한 Lock. 걸어야할까 말아야할까
- 게시판, 좋아요에 LOCK?
- PessimisticLock Scope - NORMAL / EXTENDED
- 게시물을 가져올 때 댓글까지 LOCK?
- LOCK 관련 예외 처리 전략
- 다양한 상황 연출해보기
- 트랜잭션 격리레벨에 따른 LOCK
'우아한테크코스 > 테코톡 정리' 카테고리의 다른 글
서블릿 필터 & 스프링 인터셉터 (0) | 2022.11.15 |
---|---|
JDK Dynamic Proxy vs CGLIB Proxy (3) | 2022.10.18 |
Spring AOP (0) | 2022.10.14 |
인덱스 (0) | 2022.10.14 |
CI/CD와 무중단 배포 (0) | 2022.10.09 |