일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- 알고리즘
- PYTHON
- CSS
- 완전탐색
- java
- DFS
- 플로이드-워셜 알고리즘
- HTML
- 운영체제
- redis
- jpa
- Data structure
- javascript
- spring
- Docker
- CS
- It
- 트랜잭션
- 프로그래머스
- websocket
- nosql
- 자료구조
- 데이터베이스
- 영속성 컨텍스트
- 백준
- db
- OS
- BFS
- Algorithm
- mysql
- Today
- Total
If at first you don't succeed, try again
[DB] Lock의 개념 및 테스트 본문
* 개요
좋아요 수와 관련해서 개발 공부를 진행하다가 동시성 문제에 대해 고민을 하게 되었다.
동시성 문제를 처리하는 것에는 다양한 방법이 있는데, 이 중 락(lock)에 대해 공부한 것을 정리하고자 한다.
* Record Lock
- Record(=Row) : 테이블의 행 데이터
- Lock(잠금) : 여러 프로세스 또는 스레드가 자원에 동시에 접근하는 경쟁 상태를 방지하기 위해 제한을 거는 것
- Record Lock(=Row Lock) : 레코드에 락을 거는 것, 동일한 레코드를 동시에 조회 또는 수정할 때 데이터의 무결성을 보장하고 경쟁 상태를 방지하고자 하는 것
* Record Lock 테스트
lock 테스트를 위한 lock_test 테이블을 만들고, (id = 1234, content = 'test') 레코드를 삽입한다.

create table lock_test (
id bigint not null primary key,
content varchar(100) not null
);

insert into lock_test values(1234, 'test');
트랜잭션 1을 시작하고 방금 삽입한 레코드를 업데이트 한다.
start transaction;
update lock_test
set content = 'test2'
where id = 1234;
일단 commit은 하지 않고 트랜잭션을 유지해보겠다.
새로운 터미널을 열고, id가 1234인 레코드를 조회한다.
select * from lock_test
where id = 1234;

트랜잭션1이 아직 COMMIT되지 않았으므로, 새로운 터미널(터미널 2)에서는 content = 'test'인 채로 조회가 되었다.
이번엔 새로운 터미널(터미널 2)에서 트랜잭션을 열고 id = 1234인 레코드를 수정해보겠다.
여기서 기존 터미널(터미널 1)의 트랜잭션은 COMMIT과 ROLLBACK이 되지 않고 유지되고 있다.
터미널 2에서 트랜잭션 2를 시작하고, update 구문을 다시 수행한다.
start transaction;
update lock_test
set content = 'test2'
where id = 1234;

트랜잭션 1에서는 update 구문이 즉시 처리되었는데, 트랜잭션 2에서는 계속 대기하고 있다.

결국 타임아웃으로 종료되었다.
트랜잭션 1이 점유하고 있는 lock에 의해서 트랜잭션 2는 lock이 해제될 때까지 기다리는 것으로 보인다.
다시 터미널 2에서 트랜잭션 2를 시작하고, update 구문을 수행한 상태에서 트랜잭션 1을 COMMIT해보자.

commit;

트랜잭션 1을 커밋하였다.

트랜잭션 1이 commit되자 곧 바로 터미널 2의 트랜잭션 2에서 update가 수행된 것을 확인할 수 있다.
트랜잭션 2는 트랜잭션 1이 종료될 때까지 update가 약 5초간 지연되고 있었다.
락을 오래 점유하면 치명적이다. 리소스 고갈 등으로 인해 장애가 발생할 수 있기 때문이다.
그럼 동시적으로 쓰기 요청이 들어왔을 때, 데이터 유실 또는 장애 없이 처리하기 위한 방법엔 뭐가 있을까?
그 방법들은 다음 글에서 정리하도록 하겠다.
'DB' 카테고리의 다른 글
[DB] 비관적 락(Pessimistic Lock) & 낙관적 락(Optimistic Lock) (0) | 2025.03.28 |
---|---|
[DB] 페이징 조회 쿼리 성능 개선 - MySQL (0) | 2025.03.08 |
[DB] Index 실습(대용량 데이터 처리) - MySQL (0) | 2025.03.08 |
[DB] 트랜잭션 (0) | 2025.02.07 |
[DB] SQL의 개념 (0) | 2021.09.10 |