ํฐ์คํ ๋ฆฌ ๋ทฐ
๐ ๋์์ฑ ๋ฌธ์ ํด๊ฒฐ์ ์ํด ์ด๋ค Lock์ ์ฌ์ฉํด์ผ ํ ๊น? - (1) DB Lock์๋ ๋ฌด์์ด ์์๊น? ๐
junojuno 2024. 3. 2. 20:05๐ Overview
์คํ์ด์ค ํด๋ฝ ํ๋ก์ ํธ๋ฅผ ์งํํ๋ฉด์, ์๋์ ๊ฐ์ด ํด๋ฝ์์ ํ์ฌ๋ฅผ ๊ฐ์ตํ ๋, ๊ณต์ฐ ์นดํ ๊ณ ๋ฆฌ์ ํ์ฌ๋ฅผ ์ ์ฒญํ๋ฉด ์ ์ฐฉ์ ๊ธฐ๋ฅ์ ์ ๊ณตํด์ผ ํ๋ค.
๊ทธ๋์ ์๋์ ๊ฐ์ด ํ์ฌ ๊ฐ์ต์๊ฐ ์ต๋ ์ ์(์๋๋ 100๋ช )์ ์ค์ ํด ๋์ผ๋ฉด, ์๋งค ์ฅ์๋ฅผ ์ ํํด ์ ์ฒญ์ ํด์ผ ํ๋ค.
๊ทธ๋ฆฌ๊ณ ์ ์์ด ์๋ ํ์ฌ์ธ ๊ฒฝ์ฐ ์ต๋ 999๋ช ๊น์ง ๋ฐ์ ์ ์๋๋ก ์ ์ฑ ์ ์ค์ ํ์๋ค.
์ด๋ ๋ฐ์ํ ์ ์๋ ๋ฌธ์ ์ ์ด ๋์์ฑ ๋ฌธ์ ๊ฐ ๋ฐ์ํ ์ ์์๋ค.
๋ฐ๋ผ์ ํ์ฌ๋ฅผ ์ ์ฒญํ๊ณ ์ทจ์ํ ๋ ๋์์ฑ๋ฌธ์ ๊ฐ ๋ฐ์ํ์ง ์๋๋ก, ๋น๊ด์ ๋ฝ(Pessimistic lock)์ ์ฌ์ฉํด ๋์์ฑ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ์๋ค.
๊ทธ๋ฆฌ๊ณ api ํธ์ถ ์ ์ ์ฒญ์ด ๋ถ๊ฐํ ๊ฒฝ์ฐ ๋ฐ์ํ ์คํ๋ง ์์ธ๋ฅผ ๋ณํํด์ ํ๋ก ํธ์๊ฒ ์ ๋ฌํด ์ฃผ์๋ค.
ํ๋ก์ ํธ๋ฅผ ์งํํ ๋๋, ์ผ๋จ lock์ ์ฌ๋ฌ ๋ฐฉ๋ฒ์ด ์๋ค๋ ๊ฒ์ ์๊ณ ์์๋๋ฐ, JPA์ ๋น๊ด์ ๋ฝ์ ํตํด์ DB lock์ ๊ฐ๋จํ ๊ฑธ ์ ์๊ณ , DB์ ๋ฐ์ดํฐ์ ์ ๊ทผํจ์ ์์ด ๋์์ฑ ๋ณด์ฅ์ด ํ์คํ ๋์๊ธฐ ๋๋ฌธ์ ์ฌ์ฉํ์๋ค.
ํ์ง๋ง ์ฐพ์๋ณด๋, ๋น๊ด์ ๋ฝ์ ์ฌ์ฉํ๋ค๋ฉด ์ฝ๊ธฐ๊ฐ ๋น๋ฒ ํ ๊ฒฝ์ฐ ์ฑ๋ฅ ์ ํ์ ๋ฌธ์ ๊ฐ ์๋ค๋ ๊ฒ์ ์๊ณ DB์ JPA์์ ์ ๊ณตํ๋ lock์ ์ข ๋ฅ๋ก๋ ๋ฌด์์ด ์๊ณ , ์ด๋ ๋ lock์ ์ฌ์ฉํ๋๊ฒ์ด ์ข์ ์ ํ์ธ์ง์ ๋ํ ๊ณ ๋ฏผ์ด ์๊ฒผ๋ค.
DB Lock์ ์์๋ณด์!
1. ํธ๋์ญ์ ๊ณผ Lock์ ์ฐจ์ด์ !
๋จผ์ DB์์ ์ ๊ณตํ๋ Lock์ ๋์์ฑ์ ์ ์ดํ๊ธฐ ์ํ ๊ธฐ๋ฅ์ด๋ค.
๊ทธ๋ฌ๋ฉด ํธ๋์ญ์ ์? ํธ๋์ญ์ ์ ๋ฐ์ดํฐ์ ์ ํฉ์ฑ์ ๋ณด์ฅํ๊ธฐ ์ํ ๊ธฐ๋ฅ์ด๋ค. ํธ๋์ญ์ ์ Isolation level์ ์ค์ ํ๋๋ฐ ์์ด์ DB lock์ ์ฌ์ฉํด์ ๋ฐ์ดํฐ์ ์ ํฉ์ฑ์ ๋ณด์ฅํ๋ค.
ํธ๋์ญ์ ์ ACID ์์น์ ์์ด Atomicity ์์น์ผ๋ก ์ธํด ์ ํ๋ฆฌ์ผ์ด์ ๊ฐ๋ฐ์์ ๊ณ ๋ฏผํด์ผ ํ ๋ฌธ์ ๋ฅผ ์ค์ฌ์ฃผ๋ ์์ฃผ ํ์์ ์ธ DBMS ๊ธฐ๋ฅ์ ์ ๊ณตํ๋ค. Partial Update๊ฐ ๋ฐ์ํ๋ฉด ์คํจํ ์ฟผ๋ฆฌ๋ก ์ธํด ๋จ์ ๋ ์ฝ๋๋ฅผ ๋ค์ ์ญ์ ํ๋ ๊ฒ์ ๊ฐ๋ฐ์๊ฐ ์ผ์ผ์ด ์ฑ๊ฒจ์ค์ผ ํ๊ธฐ ๋๋ฌธ์ด๋ค.
2. MySQL ์์ง์ Lock์ ๋ํด์ ์์๋ณด์!
MySQL ์์ง๊ณผ InnoDB ์คํ ๋ฆฌ์ง ์์ง์ ์ฐจ์ด๋ฅผ ๋ชจ๋ฅธ๋ค๋ฉด ์ฌ๊ธฐ๋ฅผ ์ฐธ๊ณ ํ์.
MySQL ์์ง ๋ ๋ฒจ Lock์ ๋ชจ๋ ์คํ ๋ฆฌ์ง ์์ง์ ์ํฅ์ ๋ฏธ์น์ง๋ง ์คํ ๋ฆฌ์ง ์์ง ๋ ๋ฒจ์ Lock์ ์คํ ๋ฆฌ์ง ์์ง ๊ฐ ์ํธ ์ํฅ์ ๋ฏธ์น์ง๋ ์๋๋ค.
(1) ๊ธ๋ก๋ฒ ๋ฝ (Global Lock)
FLUSH TABLES WITH READ LOCK ๋ช ๋ น์ผ๋ก ํ๋ ๊ฐ๋ฅํ๋ฉฐ MySQL์์ ์ ๊ณตํ๋ lock ๊ฐ์ด๋ฐ ๊ฐ์ฅ ๋ฒ์๊ฐ ํฌ๋ค.
MySQL ์๋ฒ ์ ์ฒด์ lock์ ๊ฑฐ๋ ๊ฒ์ด๋ฉฐ ์คํ๊ณผ ๋์์ MySQL ์๋ฒ์ ์กด์ฌํ๋ ๋ชจ๋ ํ ์ด๋ธ์ ๋ซ๊ณ lock์ ๊ฑด๋ค.
FLUSH TABLES WITH READ LOCK ์ ํ ์ด๋ธ ์ฝ๊ธฐ ์ ๊ธ ๊ฑธ๊ธฐ ์ ์ ๋จผ์ ํ ์ด๋ธ์ ํ๋ฌ์ ํ๊ธฐ ๋๋ฌธ์ ํ ์ด๋ธ์ ์คํ์ค์ธ ๋ชจ๋ ์ข ๋ฅ์ ์ฟผ๋ฆฌ๊ฐ ์๋ฃ๋์ด์ผ ํ๋ค.
๊ธ๋ก๋ฒ ๋ฝ์ ํตํด ๋ฐฑ์ ๋๋ ๋ฐ์ดํฐ ๋ง์ด๊ทธ๋ ์ด์ ์์ ์๋ฃ ํ์๋ UNLOCK TABLES ์ฌ์ฉํด์ Lock์ ํด์ ํด์ผํ๋ค.
์ฌ์ฉ์์๋ ์๋์ ๊ฐ๋ค.
START TRANSACTION;
FLUSH TABLES WITH READ LOCK;
mysqldump --all-databases > backup.sql;
UNLOCK TABLES;
COMMIT;
์ธ๊ธํ๋ค์ํผ, ๋ชจ๋ ํ ์ด๋ธ์ ํฐ ์ํฅ์ ๋ฏธ์น๊ธฐ์ ์น์๋น์ค์ฉ์ผ๋ก ์ฌ์ฉ๋๋ MySQL ์๋ฒ์์๋ ๊ฐ๊ธ์ ์ฌ์ฉํ์ง ์๋ ๊ฒ์ด ์ข๋ค.
(2) ํ ์ด๋ธ ๋ฝ (Table Lock)
ํ ์ด๋ธ ๋ฝ์ ๊ฐ๋ณ ํ ์ด๋ธ ๋จ์๋ก ์ค์ ๋๋ ๋ฝ์ด๋ค.
LOCK TABLES table_name [ READ | WRITE ] ์ฌ์ฉํด์ ๋ฝ ํ๋์ด ๊ฐ๋ฅํ๋ค.
์๋์ ๊ฐ์ด ๋ช ์์ ์ผ๋ก ์ฌ์ฉ๊ฐ๋ฅํ๋ฐ, ํ ์ด๋ธ ๋ฝ๋ ํน๋ณํ ์ํฉ์ด ์๋๋ฉด ์ ํ๋ฆฌ์ผ์ด์ ์์ ์ฌ์ฉํ ํ์๊ฐ ๊ฑฐ์ ์๋ค๊ณ ํ๋ค.
LOCK TABLES users WRITE;
# ์์
์ํ
UNLOCK TABLES;
๋ช ์์ ์ผ๋ก ํ ์ด๋ธ์ ์ ๊ทธ๋ ์์ ์ ๊ธ๋ก๋ฒ ๋ฝ๊ณผ ๊ฐ์ด ์จ๋ผ์ธ ์์ ์ ์๋นํ ์ํฅ์ ๋ฏธ์น๊ธฐ ๋๋ฌธ์ด๋ค.
๋ฌต์์ ์ผ๋ก ํ ์ด๋ธ๋ฝ์ MyISAM, MEMORY ํ ์ด๋ธ์ ๋ฐ์ดํฐ ๋ณ๊ฒฝํ๋ ์ฟผ๋ฆฌ๋ฅผ ์คํํ๋ฉด ๋ฐ์ํ๋ค. ์ฟผ๋ฆฌ๊ฐ ์คํ๋๋ ๋์ ์๋์ผ๋ก ํ๋๋์๋ค๊ฐ ์ฟผ๋ฆฌ ์๋ฃ ํ ์๋ ํด์ ๋๋ค.
ํ์ง๋ง InnoDB ํ ์ด๋ธ ๊ฒฝ์ฐ, ์คํ ๋ฆฌ์ง ์์ง ๋ ๋ฒจ์์ ๋ ์ฝ๋ ๊ธฐ๋ฐ lock์ ์ ๊ณตํ๊ธฐ์ ๋ฌต์์ ์ธ ํ ์ด๋ธ ๋ฝ ์ค์ ๋์ง ์๋๋ค. (๋ช ํํ๋ ํ ์ด๋ธ ๋ฝ์ด ๊ฑธ๋ฆฌ์ง๋ง, DML ์ฟผ๋ฆฌ๋ ๋ฌด์๋๊ณ DDL ๊ฒฝ์ฐ์๋ง ์ํฅ์ ๋ฏธ์นจ)
(3) ๋ค์๋ ๋ฝ (Named Lock)
GET_LOCK() ํจ์๋ฅผ ์ด์ฉํด์ ์์์ ๋ฌธ์์ด์ ๋ํด ์ ๊ธ ์ค์ ์ด ๊ฐ๋ฅํ๋ค.
๊ทธ๋ฅ ๋จ์ํ ์ฌ์ฉ์๊ฐ ์ง์ ํ ๋ฌธ์์ด์ ๋ํด ํ๋ํ๊ณ ๋ฐ๋ฉํ๋ lock์ด๋ค.
์ด๋ ๋์ค์ ๋ค๋ฃฐ ๋ถ์ฐ๋ฝ ๊ตฌํ์ ์ฌ์ฉ๋ ์ ์๋ค. ๋ถ์ฐ๋ฝ์ด๋ ์ฌ๋ฌ์๋ฒ์์ ๊ณต์ ๋ ๋ฐ์ดํฐ๋ฅผ ์ ์ดํ๊ธฐ ์ํด ์ฌ์ฉํ๋ ๊ธฐ์ ์ธ๋ฐ, DB์๋ฒ๊ฐ 1๋์ธ๋ฐ ๋นํด ์๋ฒ๊ฐ ์ฌ๋ฌ๋๋ก ์๋น์คํ๋ ์ํฉ์์ ๋ฐ์ดํฐ ๋๊ธฐํ ํ๊ธฐ ์ํด ์ฌ์ฉํ๋ lock์ ๋งํ๋ค.
select get_lock(key, timeout)์ ํตํด lock์ ํ๋ ํ ์ ์๋ค.
select release_lock(key)์ ํตํด์ lock์ ํด์ ํ๋ค.
์๋๋ ๋ด๊ฐ ๋์์ฑ์ ํ์ตํ๋ฉด์ ์์ฑํ ์ฝ๋์ธ๋ฐ, ์ฌ์ฉ๋ฐฉ์์ ์๋ ๋ค์๊ณผ ๊ฐ๋ค.
์ค๋ฌด์์๋ lock์ ํ๋ํ๊ณ ๋ฐ๋ฉํ๋๋ฐ ์์ด connection ๊ณ ๊ฐ์ด ์ผ์ด๋ ์ ์๊ธฐ์ datasource๋ฅผ ๋ถ๋ฆฌํ๋๊ฒ ์ข๋ค๊ณ ํ๋ค.
๋จผ์ named lock์ ํ๋ํ๊ณ ๋ฐ๋ฉ์ ๋ด๋นํ๋ repository๋ฅผ JdbcTemplate์ ์ด์ฉํด ์์ฑํด ์ฃผ์๋ค.
๊ทธ ์ด์ ๋ ํด๋น lock ์ค์ ์ ํน์ entity์ ์ข ์๋์ง ์๊ธฐ ๋๋ฌธ์ Spring Data JPA๋ฅผ ์ฌ์ฉํ๋ ๊ฒ ๋ณด๋ค JdbcTemplate์ ์ฌ์ฉํ์๋ค.
@Repository
public class NamedLockRepository {
private final JdbcTemplate jdbcTemplate;
public NamedLockRepository(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
public void getLock(String key) {
jdbcTemplate.execute("SELECT GET_LOCK('" + key + "', 10)");
}
public void releaseLock(String key) {
jdbcTemplate.execute("SELECT RELEASE_LOCK('" + key + "')");
}
}
@Component
public class NamedLockStockFacade {
private final LockRepository lockRepository;
private final StockService stockService;
public NamedLockStockFacade(LockRepository lockRepository, StockService stockService) {
this.lockRepository = lockRepository;
this.stockService = stockService;
}
@Transactional
public void decrease(Long id, Long quantity) {
String lockKey = id.toString();
try{
lockRepository.getLock(lockKey);
// critical section
stockService.decrease(id, quantity);
} finally {
lockRepository.releaseLock(lockKey);
}
}
}
(4) ๋ฉํ๋ฐ์ดํฐ ๋ฝ (Metadata Lock)
๋ฐ์ดํฐ๋ฒ ์ด์ค ๊ฐ์ฒด์ ์ด๋ฆ์ด๋ ๊ตฌ์กฐ๋ฅผ ๋ณ๊ฒฝํ๋ ๊ฒฝ์ฐ์ ํ๋ํ๋ lock์ด๋ค.
RENAME TABLE table_a TO table_b ๊ฐ์ด ํ ์ด๋ธ ์ด๋ฆ ๋ณ๊ฒฝํ๋ ๊ฒฝ์ฐ ์๋์ผ๋ก ํ๋๋๋ค. (๋ ํ ์ด๋ธ ๋ชจ๋ lock ์ค์ )
2. InnoDB ์คํ ๋ฆฌ์ง ์์ง์์์ Lock์ ๋ํด์ ์์๋ณด์!
InnoDB ์คํ ๋ฆฌ์ง ์์ง์ ๋ ์ฝ๋ ๊ธฐ๋ฐ์ ์ ๊ธ ๊ธฐ๋ฅ์ ์ ๊ณตํ๋๋ฐ, ์ ๊ธ์ ๋ณด๊ฐ ์๋นํ ์์ ๊ณต๊ฐ์ผ๋ก ๊ด๋ฆฌ๋๋ค.
๋ฐ๋ผ์ MyISAM ๋ณด๋ค ํจ์ฌ ๋ฐ์ด๋ ๋์์ฑ ์ฒ๋ฆฌ๋ฅผ ํ ์ ์๋ค.
๋ํ InnoDB์ ์ ๊ธ์ ๋ ์ฝ๋๋ฅผ ์ ๊ทธ๋ ๊ฒ์ด ์๋ ์ธ๋ฑ์ค๋ฅผ ์ ๊ทธ๋ ๋ฐฉ์์ผ๋ก ์ฒ๋ฆฌ๋๊ธฐ ๋๋ฌธ์, ๋ณ๊ฒฝํด์ผํ๋ ๋ ์ฝ๋๋ฅผ ์ฐพ๊ธฐ ์ํด ๊ฒ์ํ ์ธ๋ฑ์ค์ ๋ ์ฝ๋๋ฅผ ๋ชจ๋ ๋ฝ์ ๊ฑธ์ด์ผ ํ๋ค๋ ํน์ง์ด ์๋ค
์คํ ๋ฆฌ์ง ์์ง ์ ๊ธ์ ๋ ์ฝ๋ ๋ฝ๊ณผ ๋ ์ฝ๋์ ๋ ์ฝ๋ ์ฌ์ด๋ฅผ ์ ๊ทธ๋ ๊ฐญ(Gap)๋ฝ ๋ฑ์ด ์กด์ฌํ๋๋ฐ ํ๋์ฉ ์์๊ฐ๋ณด์!
(1) ๋ ์ฝ๋ ๋ฝ
๋ ์ฝ๋ ์์ฒด๋ง์ ์ ๊ทธ๋ ๊ฒ์ ๋ ์ฝ๋ ๋ฝ (Record Lock)์ด๋ผ๊ณ ํ๋ฉฐ, ๋ค๋ฅธ ์์ฉ DBMS์ ๋ ์ฝ๋ ๋ฝ๊ณผ ๋์ผํ ์ญํ ์ ํ๋ค.
ํ์ง๋ง ์์ ์ธ๊ธํ์ง๋ง, InnoDB ์คํ ๋ฆฌ์ง ์์ง์ ๋ ์ฝ๋ ์์ฒด๊ฐ ์๋ ์ธ๋ฑ์ค์ ๋ ์ฝ๋๋ฅผ ์ ๊ทผ๋ค๋ ๊ฒ์ด ์ฐจ์ด์ ์ด ์๋ค.
์ธ๋ฑ์ค๊ฐ ์์ผ๋ฉด ๊ทธ๋ผ ์ด์ฉ๋๊ฐ? -> ์ธ๋ฑ์ค๊ฐ ์๋๋ผ๋ ๋ด๋ถ์ ์ผ๋ก ์์ฑ๋ ํด๋ฌ์คํฐ ์ธ๋ฑ์ค๋ฅผ ์ด์ฉํด ์ ๊ธ์ ์ค์ ํ๋ค.
๋ ์ฝ๋ ๋ฝ์ ์ด๋ป๊ฒ ๊ทธ๋ผ ์ค์ ํ๋ ๊ฑธ๊น?
UPDATE, DELETE ์ฟผ๋ฆฌ๋ฅผ ํตํด ๋ ์ฝ๋๋ฅผ ์ ๋ฐ์ดํธ or ์ญ์ ๋ช ๋ น์ ์คํํ๋ฉด UPDATE, DELETEํ๋ ๋์ ๋ ์ฝ๋ ๋ฝ์ด ์ค์ ๋๋ค!
๊ทธ๋ผ SELECT ํ ๋ lock ์ค์ ์ ์ด๋ป๊ฒ ํ ๊น?
SELECT name FROM user WHERE id = 1 FOR SHARE; // ๊ณต์ ๋ฝ (์ฝ๊ธฐ ์ ๊ธ)
SELECT name FROM user WHERE id = 1 FOR UPDATE; // ๋ฐฐํ ๋ฝ (์ฐ๊ธฐ ์ ๊ธ)
์์ ๊ฐ์ด shared lock (๊ณต์ ๋ฝ)๊ณผ exclusive lock (๋ฐฐํ ๋ฝ)์ด ์กด์ฌํ๋ค.
์ด๋ฐ shared lock๊ณผ exclusive lock์ ๋ฉํฐ ํธ๋์ญ์ ํ๊ฒฝ์์ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์ผ๊ด์ฑ๊ณผ ๋ฌด๊ฒฐ์ฑ์ ์ ์งํ๊ธฐ ์ํด์ ํธ๋์ญ์ ์ ์์ฐจ์ ์งํ์ ๋ณด์ฅํ ์ ์๋ ์ฅ์น์ ๊ด๋ จ๋์ด ์๋ค (ํธ๋์ญ์ ์ ๊ฒฉ๋ฆฌ ์์ค์ ๋ฐ๋ฅธ ๋ฐ์ดํฐ ์ ํฉ์ฑ ๋ณด์ฅ์ ์ฌ์ฉ)
๋ฐ๋ผ์ ํธ๋์ญ์ ์ด ์์๋์ด shared lock๊ณผ exclusive lock์ ์ทจ๋ํ๊ณ , ํธ๋์ญ์ ์ด ์ปค๋ฐ๋๊ฑฐ๋ ๋กค๋ฐฑ๋์ด ์๋ฃ๊ฐ ๋๋ฉด lock์ด ๋ฐํ๋๋ค.
-- ํธ๋์ญ์
์์
BEGIN;
-- Shared Lock ์ค์
SELECT * FROM ํ
์ด๋ธ WHERE id = 1 FOR SHARE;
-- Exclusive Lock ์ค์
SELECT * FROM ํ
์ด๋ธ WHERE id = 2 FOR UPDATE;
-- ๋ฐ์ดํฐ ๋ณ๊ฒฝ
UPDATE ํ
์ด๋ธ SET ์ด๋ฆ = '์๋ก์ด ์ด๋ฆ' WHERE id = 1;
-- ํธ๋์ญ์
๋กค๋ฐฑ or ์ปค๋ฐ
ROLLBACK or COMMIT;
-- Shared Lock๊ณผ Exclusive Lock ๋ชจ๋ ํด์ (์ถ์ฒ : google gemini)
ํธ๋์ญ์ ์ ์ฌ์ฉํ์ง ์๋ ๊ฒฝ์ฐ, UNLOCK TABLES; ์ ํตํด ๋ช ์์ ์ผ๋ก lock์ ํด์ ํ ์ ์๋ค.
์ ๋ฆฌ :
- shared lock๊ณผ exclusive lock์ ํธ๋์ญ์ ์ด ์ข ๋ฃ์์ ์ ํด์ ๋์ง๋ง, UNLOCK TABLE ํค์๋๋ฅผ ํตํด ๋ช ์์ ์ผ๋ก ํด์ ํ ์๋ ์๋ค.
- ๋ ์ฝ๋ ๋ฝ ์ทจ๋ ๋ฐฉ๋ฒ์ 1๏ธโฃ UPDATE ์ฟผ๋ฆฌ, 2๏ธโฃ DELETE ์ฟผ๋ฆฌ, 3๏ธโฃ Shared Lock / Exclusive Lock ํ๋ ์์ ๋ฐ์ํ๋ค.
(2) Gap Lock (๊ฐญ ๋ฝ)
๊ฐญ ๋ฝ์ ๋ ์ฝ๋ ์์ฒด๊ฐ ์๋ ๋ ์ฝ๋์ ๋ฐ๋ก ์ธ์ ํ ๋ ์ฝ๋ ์ฌ์ด์ ๊ฐ๊ฒฉ๋ง์ ์ ๊ทธ๋ ๊ฒ์ผ๋ก, ๋ ์ฝ๋์ ๋ ์ฝ๋ ์ฌ์ด์ ๊ฐ๊ฒฉ์ ์๋ก์ด ๋ ์ฝ๋๊ฐ ์์ฑ (insert) ๋๋ ๊ฒ์ ์ ์ดํ๋ค.
๊ฐญ๋ฝ์ ๋ํด์๋ ์๋ ๋น๊ทผ๋ง์ผ ๋ธ๋ก๊ทธ์์ ์์ธํ ๋ค๋ฃจ๊ณ ์๋ค.
(3) Next Key Lock (๋ฅ์คํธ ํค ๋ฝ)
๋ ์ฝ๋ ๋ฝ๊ณผ ๊ฐญ ๋ฝ์ ํฉ์ณ ๋์ ํํ์ ์ ๊ธ์ ๋งํ๋ค.
๊ฐญ ๋ฝ, ๋ฅ์คํธ ํค ๋ฝ์ ๋ชฉ์ ์ ๋ฐ์ด๋๋ฆฌ ๋ก๊ทธ์ ๊ธฐ๋ก๋๋ ์ฟผ๋ฆฌ๊ฐ replica server์์ ์คํ๋ ๋ source server์์ ๋ง๋ค์ด ๋ธ ๊ฒฐ๊ณผ์ ๋์ผํ ๊ฒฐ๊ณผ๋ฅผ ๋ง๋ค์ด ๋ด๋๋ก ๋ณด์ฅํด ์ฃผ๋ ๊ฒ์ด ์ฃผ ๋ชฉ์ ์ด๋ค.
์๋ฅผ๋ค์ด, UPDATE tb_gaplock SET .. WHERE id BETWEEN 1 AND 3 ์ฟผ๋ฆฌ๋ฅผ ์คํํ๋ฉด, 1,3๋ฒ row + 1,3 row ์ฌ์ด๋ ์ ๊ทผ๋ค.
๋ฐ๋ผ์ ์ค์ ์ ๋ฌด ํ๋ก๊ทธ๋จ์์๋ ์ด๋ฐ Next Key Lock์ด ๋ ์ผ๋ฐ์ ์ผ๋ก ์ฌ์ฉ ๋๋ค๊ณ ํ๋ค.
(4) Auto Increment Lock (์๋ ์ฆ๊ฐ ๋ฝ)
AUTO_INCREMENT ์นผ๋ผ์ด ์ ์ฉ๋ ํ ์ด๋ธ์ ๋์์ ์ฌ๋ฌ ๋ ์ฝ๋๊ฐ insert ๋๋ ๊ฒฝ์ฐ, ์ ์ฅ๋๋ ๊ฐ ๋ ์ฝ๋๋ ์ค๋ณต๋์ ์๊ณ ์์๋๋ก ์ฆ๊ฐํ๋ ์ผ๋ จ๋ฒํธ๋ฅผ ๊ฐ์ ธ์ผ ํ๊ธฐ ๋๋ฌธ์ ๋ด๋ถ์ ์ผ๋ก auto_increment lock์ด๋ผ๋ ํ ์ด๋ธ ์์ค์ lock์ ์ฌ์ฉํ๋ค.
๋ฐ๋ผ์ INSERT, REPLACE ๋ฌธ์์๋ง ํ์ํ๋ฉฐ, UPDATE, DELETE ์ฟผ๋ฆฌ์์๋ ๊ฑธ๋ฆฌ์ง ์๋๋ค.
ํธ๋์ญ์ ๊ณผ ๊ด๊ณ ์์ด auto_increment ๊ฐ ๊ฐ์ ธ์ค๋ ์๊ฐ๋ง ๋ฝ ๊ฑธ๋ ธ๋ค๊ฐ ์ฆ์ ํด์ ๋๋ฉฐ, ํ ์ด๋ธ์์ lock์ ๋จ ํ๋๋ง ์กด์ฌํ๋ค.
Reference
Real MySQL 8.0 Chapter 5
์ฐธ๊ณ ์๋ฃ๋ ๋ ธ์ ์ ๋ ์ถ๊ฐ์ ์ผ๋ก ๊ธฐ๋กํด ๋์๋ค.
https://techblog.woowahan.com/2631/
https://dev.mysql.com/doc/refman/8.0/en/locking-functions.html
'Programming > Database' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
- Total
- Today
- Yesterday