MySQL SELECT FOR UPDATE 동작방식

2022년 11월 03일

mysql

# MySQL# InnoDB# 8.0

들어가며

SELECT ... FOR SHARE
  • 읽은 모든 행에 공유 모드 잠금을 설정
  • 다른 세션은 행을 읽을 수 있지만 트랜잭션이 커밋될 때까지 수정할 수 없다.
  • 아직 커밋되지 않은 다른 트랜잭션에 의해 이러한 행이 변경된 경우 쿼리는 해당 트랜잭션이 종료될 떄까지 기다린 다음 최신 값을 사용합니다.

예전에는 이렇게 쓴거같다.

SELECT ... LOCK IN SHARE MODE

MySQL 8.0.22 이전에는 SELET … FOR SHARE 권한 혹은 SELECT 중 하나 이상이 필요

MySQL 8.0.22부터 SELECT ... FOR SHARE 명령문은 MySQL 권한 부여 테이블에 대한 읽기 잠금을 획득하지 않는다.

SELECT ... FOR UPDATE

사전 준비

Docker를 통해서 MySQL 실행하기

docker pull mysql:latest

mysql container 띄우기

docker run --name mysql-container -e MYSQL_ROOT_PASSWORD=<루트 패스워드> -d -p 3306:3306 mysql:latest

mysql 접속하기

  • 2개의 세션을 연결하여 테스트
docker exec -it mysql-container bash

2개의 세션이 연결되었는지 확인

mysql> show processlist;
+----+-----------------+-----------+------------+---------+-------+------------------------+------------------+
| Id | User            | Host      | db         | Command | Time  | State                  | Info             |
+----+-----------------+-----------+------------+---------+-------+------------------------+------------------+
|  5 | event_scheduler | localhost | NULL       | Daemon  | 34795 | Waiting on empty queue | NULL             |
| 10 | root            | localhost | lock_tests | Sleep   |    31 |                        | NULL             |
| 11 | root            | localhost | lock_tests | Query   |     0 | init                   | show processlist |
+----+-----------------+-----------+------------+---------+-------+------------------------+------------------+
3 rows in set (0.00 sec)

테스트용 테이블 생성

mysql> CREATE TABLE `coffee` (
                `id` INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
                `name` varchar(255) NOT NULL COMMENT '커피 이름'
            ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

시나리오 1

  1. Primary Key를 이용해서 조회 시 Row Level 단위로 락이 걸린다.

session 1

START TRANSACTION;
SELECT * FROM coffee id = 1 FOR UPDATE;
+----+-------+
| id | name  |
+----+-------+
|  1 | latte |
+----+-------+

session 2

START TRANSACTION;
SELECT * FROM coffee WHERE id = 1 FOR UPDATE;
--; 대기 중

참고자료

© 2025, 미나리와 함께 만들었음