๐ป [Theory] JPA์ ๋๊ด์ ์ ๊ธ(Optimistic Lock), ๋น๊ด์ ์ ๊ธ(Pessimistic Lock)
๐ป [Theory] JPA์ ๋๊ด์ ์ ๊ธ(Optimistic Lock), ๋น๊ด์ ์ ๊ธ(Pessimistic Lock)
์ ํ๋ฆฌ์ผ์ด์
์ ๊ฐ๋ฐํ๋ค๋ณด๋ฉด ์ฌ๋ฌ ๋์์ฑ ๋ฌธ์ ๋ค์ ๋ง๋๊ณ ๋์์ฑ ์ ์ด๋ฅผ ๋์์ฃผ๋ ์ฌ๋ฌ ์์คํ
๋ค(๋ฐ์ดํฐ๋ฒ ์ด์ค ์์คํ
, JPA ์์คํ
๋ฑ) ์ ๋ณด๊ฒ๋ฉ๋๋ค.
ํนํ๋ ๋ง์ ์ฌ์ฉ์๊ฐ ์๋ ์ ํ๋ฆฌ์ผ์ด์
์ผ ์๋ก ๋์์ฑ ๋ฌธ์ ๊ฐ ๋ ์ค์ํ๊ณ ์ด๋ฅผ ์ ์ดํด์ฃผ์ด์ผ ํฉ๋๋ค.
๋์์ฑ ์ ์ด๋ฅผ ๋์์ฃผ๋ ๋ฐฉ๋ฒ๋ค ์ค
์ด๋ฒ์ JPA ์์คํ
์์์ ๋๊ด์ ์ ๊ธ(Optimistic Lock), ๋น๊ด์ ์ ๊ธ(Pessimistic Lock)์ ๋ํด ์์๋ณด๊ฒ ์ต๋๋ค.
Locking์ด๋ ?
- ์ ํ๋ฆฌ์ผ์ด์
์ ๊ฐ๋ฐํ๋ค๋ณด๋ฉด ์ฌ๋ฌ ๋์์ฑ ๋ฌธ์ ๋ค์ ๋ง๋๊ฒ ๋จ.
- ex) read skew, lost update ๋ฑ๋ฑ
- ์ฌ๋ฌ ๋์์ฑ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํด์ ๊ทธ ์ค์์๋ ๋ฐ์ดํฐ์ ์ผ๊ด์ฑ์ ์งํค๊ธฐ ์ํ ๋ฐฉ๋ฒ ์ค ํ๋์ด๋ค.
๋๊ด์ ์ ๊ธ(Optimistic Lock)
- ๊ธฐ๋ณธ์ ์ผ๋ก ๋ฐ์ดํฐ ๊ฐฑ์ ์ ์ถฉ๋์ด ๋ฐ์ํ์ง ์์๊ฒ์ด๋ผ๊ณ ๋๊ด์ ์ผ๋ก ๋ณด๋ ๊ฒ.
- ๋ฐ์ดํฐ ๊ฐฑ์ ์ ์ถฉ๋์ด ๋ฐ์ํ์ง ์์ ๊ฒ์ผ๋ก ์์ํ๊ธฐ ๋๋ฌธ์, ์ฐ์ ์ ์ผ๋ก ๋ฝ์ ๊ฑธ์ง ์๋๋ค.
- Version์ ์ฌ์ฉํด ๊ด๋ฆฌํ๋ค.
- ์ดํ๋ฆฌ์ผ์ด์ ๋ฝ
- ์ถฉ๋๋ฐฉ์ง
- ํธ๋์ญ์ ์ ์ปค๋ฐํ๊ธฐ ์ ๊น์ง๋ ํธ๋์ญ์ ์ ์ถฉ๋์ ์ ์ ์๋ค.
- ๊ฐ๋จํ @Version ์ด๋
ธํ
์ด์
์ ์ด์ฉํด ์ฌ์ฉ์ด ๊ฐ๋ฅํ๋ค. ๋จ, ๋ค์๊ณผ ๊ฐ์ ์ฃผ์์ฌํญ์ด ์๋ค.
- ๊ฐ ์ํฐํฐ ํด๋์ค์๋ ํ๋์ ๋ฒ์ ์์ฑ ๋ง ์์ด์ผํ๋ค.
- ์ฌ๋ฌ ํ ์ด๋ธ์ ๋งคํ ๋ ์ํฐํฐ์ ๊ฒฝ์ฐ ๊ธฐ๋ณธ ํ ์ด๋ธ์ ๋ฐฐ์น๋์ด์ผํ๋ค๋ค.
- ๋ฒ์ ์ ๋ช ์ํ ํ์ ์ int, Integer, long, Long, short, Short, java.sql.Timestamp ์ค ํ๋ ์ฌ์ผํ๋ค.
๋๊ด์ ์ ๊ธ(Optimistic Lock) ์ฒ๋ฆฌ๋ฐฉ๋ฒ
- ๋๊ด์ ์ ๊ธ์ OptimisticLockException์ ๋ฐ์์ํจ๋ค.
- Persistence Provider๊ฐ Entity์์ ๋๊ด์ ์ ๊ธ ์ถฉ๋์ ๊ฐ์งํ๋ฉด OptimisticLockException์ ๋ฐ์์ํค๊ฒ ๋๊ณ ํธ๋์ญ์ ์ ๋กค๋ฐฑ์ ์ฒ๋ฆฌํ๋ค.
- ๊ถ์ฅ๋๋ ์์ธ์ฒ๋ฆฌ ๋ฐฉ๋ฒ์์๋ Entity๋ฅผ ๋ค์ ๋ก๋ํ๊ฑฐ๋ ์๋ก๊ณ ์นจํ์ฌ ์ ๋ฐ์ดํธ๋ฅผ ์ฌ์๋ํ๋ ๋ฐฉ๋ฒ์ด๋ค.
- ์์ธ์ฒ๋ฆฌ์์ ๋ฐ์๋๋ Exception์์ ์ถฉ๋๋๋ Entity๋ฅผ ์ ๊ณตํด์ฃผ๊ณ ์์ด ์ฝ๊ฒ ์ฒ๋ฆฌ๊ฐ ๊ฐ๋ฅํ๋๋ก ๋์ด์๋ค.
๋น๊ด์ ์ ๊ธ(Pessimistic Lock)
- ๊ธฐ๋ณธ์ ์ผ๋ก ๋ฐ์ดํฐ ๊ฐฑ์ ์ ์ถฉ๋์ด ๋ฐ์ํ ๊ฒ์ด๋ผ๊ณ ๋น๊ด์ ์ผ๋ก ๋ณด๊ณ ๋ฏธ๋ฆฌ ์ ๊ธ์ ๊ฑฐ๋ ๊ฒ
- ๋ฐ์ดํฐ ๊ฐฑ์ ์ ์ถฉ๋์ด ๋ฐ์ํ์ง ์์ ๊ฒ์ผ๋ก ์์ํ๊ธฐ ๋๋ฌธ์, ์ฐ์ ์ ์ผ๋ก ๋ฝ์ ๊ฑด๋ค(์กฐํํ ๋ ๋ถํฐ ๊ฑด๋ค).
- ํธ๋์ญ์ ์ ์ถฉ๋์ด ๋ฐ์ํ๋ค๊ณ ๊ฐ์ ํ๊ณ ์ฐ์ ๋ฝ์ ๊ฑธ๊ณ ๋ณด๋ ๋ฐฉ๋ฒ
- ํธ๋์ญ์ ์์์ ์๋น์ค๋ก์ง์ด ์งํ๋์ด์ผํจ.
- DB ๊ฐ ์ ๊ณตํ๋ ๋ฝ ๊ธฐ๋ฅ์ ์ฌ์ฉ( ex: ๊ณต์ ๋ฝ- LOCK IN SHARE MODE, ๋ฒ ํ๋ฝ-FOR UPDATE โฆ)
- ๋ฌด๊ฒฐ์ฑ์ ์ฅ์
- ๋ฐ๋๋ฝ์ ์ํ์ฑ
- ๋ฐ์ดํฐ๋ฅผ ์์ ์ ์ฆ์ ํธ๋์ญ์ ์ถฉ๋์ ์ ์ ์๋ค
์์์ ์ ๊ธ๊ณผ ๋ช ์์ ์ ๊ธ
์์์ ์ ๊ธ (Implicit Lock)
- JPA์์๋ @Version์ด ๋ถ์ ํ๋๊ฐ ์กด์ฌํ๊ฑฐ๋ @OptimisticLocking ์ด๋ ธํ ์ด์ ์ด ์ค์ ๋์ด ์์ ๊ฒฝ์ฐ ์๋์ ์ผ๋ก ์ถฉ๋๊ฐ์ง๋ฅผ ์ํ ์ ๊ธ์ด ์คํ๋๋ค.
- ์ด๋ Annotation๋ง ์ค์ ํด์ฃผ๋ฉด ๋ณ๋์ ์ถ๊ฐ ์ค์ ์ด ์์ด๋ JPA์์ ์๋์ ์ผ๋ก ํํ์ฌ์ฃผ๋ ์ ๊ธ์ด๋ค.
- ์ถ๊ฐ๋ก ์ญ์ ์ฟผ๋ฆฌ๊ฐ ๋ฐ์ํ ์์๋ ์์์ ์ผ๋ก ํด๋น ๋ก์ฐ์ ๋ํ ํ ๋ฐฐํ์ ๊ธ(Row Exclusive Lock)์ ์ ๊ณตํ์ฌ์ค๋ค.
๋ช ์์ ์ ๊ธ (Explicit Lock)
- ํ๋ก๊ทธ๋จ์ ํตํด ์๋์ ์ผ๋ก ์ ๊ธ์ ์คํํ๋ ๊ฒ์ด ๋ช ์์ ์ ๊ธ์ด๋ค.
-
JPA์์ EntityManager๋ฅผ ํตํ์ฌ ์ํฐํฐ๋ฅผ ์กฐํํ ๋ LockMode๋ฅผ ์ง์ ์ง์ ํ๊ฑฐ๋ select for update ์ฟผ๋ฆฌ๋ฅผ ํตํด์ ์ง์ ์ ๊ธ์ ์ง์ ํ ์ ์๋ค.
Student student = entityManager.find(Student.class, id); entityManager.lock(student, LockModeType.OPTIMISTIC);
Student resultStudent = entityManager.find(Student.class, studentId); entityManager.lock(resultStudent, LockModeType.PESSIMISTIC_WRITE);
์ ๋ฆฌ
- ํธ๋์ญ์ ์ถฉ๋์ด ์ ๋ฐ์ํ์ง ์๋ ํ๊ฒฝ์์๋ ๋๊ด์ ์ธ ๋ฝ์ด ์ข๊ณ ์ถฉ๋์ด ์์ฃผ ๋ฐ์ํ๋ ํ๊ฒฝ์์๋ ๋น๊ด์ ์ธ ๋ฝ์ด ์ข๋ค.
- ๋๊ด์ ์ธ ๋ฝ(Optimistic Lock)์ ์ฑ๋ฅ์์ ์ด์ ์ ๊ฐ๋๋ค.
- ๋น๊ด์ ์ธ ๋ฝ(Pessimistic Lock)์ ์ฐ์ ์ ์ผ๋ก ๋ฐ์ดํฐ๋ฒ ์ด์ค๋จ์์ ์ ๊ธ์ ๊ฑฐ๋ฏ๋ก ๋ฐ์ดํฐ์ ๋ํ ๋ฌด๊ฒฐ์ฑ, ์ ํฉ์ฑ์ ์ด์ ์ ๊ฐ๋๋ค.
- ๊ฒฐ๊ตญ, locking ๊ธฐ๋ฒ์ ์ ๋ต์ด ์๋ ๊ฒ์ ์๋๋ฏ๋ก ๊ฐ ์ํฉ์ ๋ง๊ฒ ์๋ง์ ์ฌ์ฉ๋ฒ์ด ํ์ํ๋ค.
๋
๋๊ด์ ์ ๊ธ(Optimistic Lock), ๋น๊ด์ ์ ๊ธ(Pessimistic Lock)์ ๋ํด ์์๋ณด์์ต๋๋ค.
๊ฐ์ฌํฉ๋๋ค. ๐
Reference
https://velog.io/@lsb156/JPA-Optimistic-Lock-Pessimistic-Lock
Written on July 2, 2021