๐ ์ํ ํฌ์ํ๊ธฐ ์๋น์ค Lock๊ธฐ๋ฒ ๊ฐ์ ์
ํฌ๋ก์ ํฌ์ ์๋น์ค๋ ๋ค์๊ณผ ๊ฐ๋ค.
์ด๋, ํฌ์์ ์ฒญ ๊ธฐ๋ก ๋ก์ง์์ Lock๊ธฐ๋ฒ์ด ์ ์ฉ๋์ด์๋ค.
Lock๊ธฐ๋ฒ์ ์ฌ๋ฌ ์์ฒญ์ด ๊ฐ์ ๋ฆฌ์์ค์ ์ ๊ทผํ๋ ค ํ ๋, ํ ๋ฒ์ ํ๋์ ์์ฒญ๋ง์ ์ฒ๋ฆฌํ๋๋ก ๋ง๋ ๊ธฐ๋ฒ์ด๋ค.
๋ฐ์ดํฐ ์ ํฉ์ฑ์ด ๋ฌด์๋ณด๋ค ์ค์ํ ์๋น์ค์์ ์ถฉ๋์ ๋ฐฉ์งํ์ฌ ์ผ๊ด์ฑ์ ํจ๊ณผ์ ์ผ๋ก ์ ์งํ๊ธฐ ์ํจ์ด๋ค.
ํฌ๋ก ์๋น์ค์ ๊ฒฝ์ฐ
, ํ์ idx๋ก lock์ ์ ์งํ์ฌ ์ฑ๋ฅ๊ณผ ์์ ์ฑ ํ๋ณด
-์ํ๋ณ ํ๋ / ํฌ์์ ์ผ๋ณ ํฌ์์ํ / ํฌ์ ๊ธ์ก / ์์น๊ธ ๋ฑ ์ ํฉ์ฑ์ด ๋ฌด์๋ณด๋ค ์ฐ์ ์ ๋๋ ๋ฐ์ดํฐ๋ค์ด ํฌํจ
synchronized
ํค์๋ ์ฌ์ฉ(JVM ๋ ๋ฒจ Lock)
import org.springframework.stereotype.Service;
@Service
public class SynchronizedLockService {
private int counter = 0;
public synchronized void increment() {
counter++;
System.out.println(Thread.currentThread().getName() + " - ํ์ฌ ์นด์ดํธ: " + counter);
}
}
(DB๋ฅผ ํ์ฉํ์ฌ Lock๊ตฌํ)
CREATE TABLE lock_table (
id INT PRIMARY KEY,
locked BOOLEAN NOT NULL DEFAULT FALSE
);
@Transactional
public void doSomethingWithLock() {
// ํ ์ ๊ธ (SELECT FOR UPDATE)
jdbcTemplate.queryForObject("SELECT * FROM lock_table WHERE id = 1 FOR UPDATE", (rs, rowNum) -> rs.getInt("id"));
System.out.println(Thread.currentThread().getName() + " - ๋ฐ์ดํฐ๋ฒ ์ด์ค Lock ํ๋!");
try {
Thread.sleep(5000); // ์์
์ํ
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + " - ์์
์๋ฃ!");
}
๋์์ฑ ์ด์๋ฅผ ๋์ํด์ผํ ๊ณณ.
๋ชจ์ง๊ธ์ก
๊ณผ, ์ํ ๋ณ ๋์ผ ์ฐจ์ฃผ ํฌ์ ํ๋
๋ฅผ ๋์ง ์๊ฒ ์ํ์ ๋์์ฑ ์ด์์ฐ๋ฆฌ๋ ์ธ๋ถ์ํ์ ํฌ์์,๋์ถ์ ๋์ ๋ชจ๋ ๋งก๊ฒจ๋๊ณ ์ด์(์ ํ ์ด์)์ค์ด๋ค.
์ค์ ๋์ด ๋น ์ ธ๋๊ฐ๋ ์์ ์, ๋ชจ๋ ํฌ์๊ธฐ๋ก์ ๋ง์น ํ, ๋์ถ์ ์คํํ๋ ์์ ์์ ๋์ ๊ฐ์ ธ๊ฐ๋ค.
์ธ๋งํฌ์ด ๋ฎคํ ์ค ๋น๊ด์ ๋ฝ ๋ฑ ์ฌ๋ฌ ๋ฐฉ๋ฒ๋ก ์ด ์์ง๋ง, ์ฐ๋ฆฌ๋ redisson lock์ ์ฌ์ฉํ์๋ค.
๋จผ์ , ํฌ๋ก ํฌ์ํ๊ธฐ
์๋น์ค๋ redisson lock์ ์ฌ์ฉํ๋ค.
Lock testLock = redissonClient.getLock("affterProcessorLock-" + Idx);
testLock.tryLock(4, 4, TimeUnit.SECONDS);
// ...ํฌ์ ๋ก์ง
testLock.unlock();
๋จ์ผ ์๋ฒ ํ๊ฒฝ์์๋ synchronized
, ์ผ๋ฐ Lock
์ ํตํด ์๊ณ ๊ตฌ์ญ์ ๋ณดํธํ ์ ์๋ค.
ํ์ง๋ง, ๋ฉํฐ์๋ฒ(๋ถ์ฐ ์์คํ
) ํ๊ฒฝ์์๋ ์ด๋ฐ
์๊ณ๊ตฌ์ญ(Critical Section) : ์ฌ๋ฌ ํ๋ก์ธ์ค ๋๋ ์ค๋ ๋๊ฐ ๊ณต์ ์์(Shared Resource) ์ ์ ๊ทผํ๋ ์ฝ๋ ์์ญ
์ฑ๊ธ์ค๋ ๋ ํ ๋ฐฉ์์ Redis๋ ์ ์์๋ฅผ ๋ณด์ฅํ์ง ์๋๊ฐ?
FIFO ๋ฐฉ์์ "๊ณต์ ๋ฝ(Fair Lock)"๋ํ ์ง์ํ์ฌ ์ํ๋ ๋ฐ ์ฌ์ฉ ๊ฐ๋ฅํ๋ค.
์ด๋ฌํ ๋์ ๋ฐฉ์ ๋๋ฌธ์, Starvation(๊ธฐ์ ํ์)์ด ์ผ๊ธฐ๋๋ ๋ฌธ์ ๊ฐ ์๋ค.
๊ธฐ์ํ์์ด๋, ๊ณ ๋ถํ ํ๊ฒฝ์์ ๋ฝ์ ํญ๋ํ๋ ค๋ ํด๋ผ์ด์ธํธ๊ฐ ๋ง์ผ๋ฉด, ํ์์ ์์ฒญ์ด ๊ณ์ํด์ ๋ฌด์๋ ๊ฐ๋ฅ์ฑ์ด ์๊ธฐ๊ธด๋ค. ์ฆ, Aํฌ์์๊ฐ ๋จผ์ ํฌ์๋ฅผ ํ์์์๋ ๋ถ๊ตฌํ๊ณ ๊ทธ ๋ค์์ ์คํํ ํฌ์์ B,C๊ฐ ๋จผ์ ์ฒ๋ฆฌ๋ ์ ์๋ค๋๊ฒ์ด๋ค.
๊ทธ๋ฆฌ๊ณ ์ค์ ์ด์ ํ๊ฒฝ์์ ํด๋น ๊ฒฝ์ฐ๋ฅผ ์ฌ์ฌ์น ์๊ฒ ์ฐพ์๋ณผ ์ ์๋ค.
ํด๋น ์ง๋ฌธ์ ๋ํ ๋ต์, ๋ถ์ฐํ๊ฒฝ์์ ๊ณ ๋ถํ apiํต์ , I/O ์์ ์ ์ํํ๋ฉฐ ์ ์ ํ ํผํฌ๋จผ์ค๋ฅผ ์ ์งํ๊ธฐ ์ํ ํํ์ ์ด๋ผ๊ณ ๋ณผ ์ ์๋ค.
์ฌ๋ด ์ ์ฑ ์ ๋ฌธ์ ๋ํ ์กด์ฌํ๊ธฐ ๋๋ฌธ์, ๋ชจ๋ ๋ถ๋ถ์์ ์๋ฒฝํ๊ธฐ๋ ์ฝ์ง ์์ ๋ณด์ธ๋ค.
์ด์ฉจ์??
(1๋ฒ ์ด์์ ๊ฐ์ ํด๊ฒฐ ๋ฐฉ๋ฒ)
ํ์ฌ ์ ํ ์ด์์ผ๋ก ์ธํ ํ๋ ๋ฐ์ดํฐ๋ฅผ ์ง์ ๊ด๋ฆฌํ์ง ๋ชปํ๋ ๋ฌธ์ ์,
๋ณด์์ ์ธ ์ด์์์ ๋ฐฉ์นจ์ผ๋ก ํฐ ๊ตฌ์กฐ ๊ฐ์ ์ ํ๋ค์ด ๋ณด์
ํ์ฌ๋ ๋ฆฌํํ ๋ง์ ํตํด lock์ ๋ฌถ์ฌ์๋ ๋ก์ง์ ๋จ์ํ ํ๋๊ฒ์ ๋ง์กฑํด์ผ๊ฒ ์.