
이번에는 MySQL에 대한 기본 문법부터 트랜잭션, 락에 대해 알아보겠습니다.
1. MySQL 기본 문법
SQL 문법은 "무엇을, 어디서, 어떻게 가져올 것인가"의 조합입니다.
(1) SELECT (데이터 조회)

- SELECT : 보고 싶은 컬럼
- FROM : 어디서
- WHERE : 조건
- ORDER BY : 정렬
- LIMIT : 개수 제한
(2) JOIN (테이블 연결)

- INNER JOIN : 양쪽 모두에 존재하는 행만
- LEFT JOIN : 왼쪽 테이블은 다 포함, 오른쪽이 없으면 NULL
ex) 직원, 부서 테이블을 연결하면, 직원 이름 + 소속 부서명까지 한 번에 조회 가능
(3) GROUP BY + HAVING (그룹 집계)

- WHERE vs HAVING 구분 : WHERE는 집계 전, HAVING은 집계 후
- NULL 주의 : COUNT(col)은 NULL 제외, COUNT(*)는 행 개수
(4) 서브쿼리/EXISTS

2. 트랜잭션(Transaction) — "모두 성공하거나, 전부 취소하기"
2-1. 개념
트랜잭션이란 여러 개의 SQL 작업을 하나의 논리적 단위로 묶어서,
전부 성공하거나(Commit), 전부 실패하면 되돌리는(Rollback) 기능입니다.
은행에서 A가 B에게 10만원을 보낸다고 해봅시다.
1. A 계좌에서 10만원 출금
2. B 계좌에 10만원 입금
이 두 과정 중 하나라도 실패하면, 돈이 사라지거나 생기겠죠 ?
그래서 DB는 이 두 작업을 하나의 묶음으로 처리합니다.
2-2. 기본 사용

2-3. Autocommit과 암묵적 커밋
- MySQL 기본은 autocommit=1 (쿼리 한 번에 자동 커밋)
- 명시적으로 여러 문장을 묶을 땐 START TRANSACTION으로 autocommit 구간을 잠깐 끄는 느낌
- DDL(CREATE/ALTER/DROP)은 암묵적 커밋 유발 → 트랜잭션 블록 안에 DDL 섞지 말 것

2-4. SAVEPOINT로 부분 되돌리기

부분 롤백 시나리오가 필요한 곳에서 유용합니다.
2-5. 송금 예시
1) 비즈니스 키로 중복 방지(멱등성)
- transfer_id 같은 고유 요청 ID를 테이블에 UNIQUE로 저장
- 같은 요청이 재전송돼도 한 번만 처리

2) 잔액 충분성 체크 + 업데이트를 한 트랜잭션으로

3) 에러 처리
- 예외 발생 시 반드시 ROLLBACK
- 애플리케이션 레벨에서 재시도 정책(특히 데드락/타임아웃)에 대비
3. 락(Lock) — "다른 사람이 동시에 건드리지 못하게"
3-1. 개념
락은 데이터 일관성을 지키기 위해,
특정 데이터에 잠금을 걸어 동시 접근을 제한하는 기능입니다.
은행에서 A의 돈을 옮기는 중인데,
다른 트랜잭션이 동시에 A의 잔액을 수정하면?
→ 값이 꼬이기 때문에 MySQL은 잠금(lock)을 겁니다.
3-2. 락의 종류
| 공유 락 (Shared Lock) | 읽기는 허용, 수정은 금지 (SELECT 시 발생) |
| 배타 락 (Exclusive Lock) | 읽기·수정 모두 금지 (UPDATE, DELETE 시 발생) |
| 테이블 락 / 행 락 | 테이블 전체 vs 특정 행만 잠금 |
3.3 락을 의도적으로 거는 읽기 (Locking Read)
- 갱신 전 선점해서 경합을 줄이는 패턴

3.4 UPDATE/DELETE의 잠금 범위는 "조건 + 인덱스"에 달려 있다

핵심 : 인덱스를 타는 WHERE가 아니면, 불필요하게 넓은 범위를 잠가서 경합/대기/타임아웃의 원인이 된다.
3.5 데드락(Deadlock) 이해 & 대처
- 서로가 서로의 락을 기다리는 "교착" 상태
- MySQL은 자동으로 한쪽을 희생(롤백) 시켜 풀어줌 → 앱에서 재시도 필요
피하는 팁
- 항상 같은 순서로 행을 갱신 (예: id 오름차순으로 잠금)
- 큰 트랜잭션을 작게 쪼개기
- 불필요한 범위 잠금 줄이기(좋은 인덱스, 정확한 WHERE)
- 읽기-쓰기 혼합 시, 쓰기 대상은 먼저 잠그기(FOR UPDATE)
3.6 테이블 락 (가급적 지양)

- InnoDB의 장점(행 단위 잠금)을 포기하게 되므로 특수한 상황에서만 사용
- 유지보수성/동시성에 부정적 영향이 큼
이번 글은 핵심 요약정리와 함께 마무리하겠습니다 !
- SELECT/JOIN/GROUP BY/HAVING : 필요한 컬럼만 선택
- WHERE - GROUP BY - HAVING 순으로 사고
- 트랜잭션 : START TRANSACTION ~ COMMIT/ROLLBACK으로 작업 단위 보장
- 락 : FOR UPDATE/FOR SHARE로 의도적 잠금
'SQL' 카테고리의 다른 글
| [TIL] MySQL에서 피벗테이블 만들기 (2) | 2025.09.30 |
|---|