2024. 1. 28. 06:11γBackend/Spring
μ μ§μ₯μμ NestJS - TypeOrmμ ν΅ν΄ κ°λ°μ μ§νν΄μκ³ , ν΄μ¬ ν Springμ νλ² μ λ¬Έν΄λ³΄μλ μκ°μΌλ‘ κ°λ¨ν νλ‘μ νΈλ₯Ό μ§ν μ€μ λλ€.
μ²μ ꡬμνλ μμ£Ό κΈ°μ΄μ μΈ κΈ°λ₯λ§ κ΅¬νν λ€ μ£Όλ³μ κ³μ μ€νλ§ κ°λ°μ λΆκ» κ°λ¨ν μ½λ 리뷰λ₯Ό λ°μλλ°, @Transactional μ΄λ Έν μ΄μ μ νμ©μ λν΄ λ°μ λ¦¬λ·°κ° νΉν κΈ°μ΅μ΄ λ©λλ€.
μ΄ λ μ무λλ κΈ°μ‘΄ TypeOrm κΈ°λ° νΈλμμ μ²λ¦¬μ μ΅μν΄μ Έμλ μν©μ΄κ³ , Spring 컨ν μ€νΈμμ DB κ΄λ ¨ μ²λ¦¬λ₯Ό μ΄λ»κ² μννλμ§ μ ν λͺ¨λ₯΄λ μν©μ΄λΌ μ΄μ λν΄ κ°μΈμ μΌλ‘ 곡λΆν΄λ³΄κΈ° μν΄ ν΄λΉ ν¬μ€νΈλ₯Ό μμ±ν©λλ€.
@Transactionalμ΄λ
μ΄λ Spring λ±μμ κ°λ¨ν μ΄λ Έν μ΄μ μ μ€μ νλ κ² λ§μΌλ‘ νΈλ¦¬νκ² νΈλμμ μ λ€λ£° μ μκ² ν΄μ£Όλ 주체μ λλ€.
μ΄λ₯Ό μ¬μ©νλ©΄ λ±λ‘λ λ©μλκ° νΈμΆλ λ νλ‘μλ₯Ό ν΅ν΄ μλμ μΌλ‘ νΈλμμ μ μλͺ μ£ΌκΈ°λ₯Ό μμ±ν΄μ£Όμ΄ κ°λ°μλ νΈλμμ κ΄λ¦¬λ₯Ό μ κ²½μ°μ§ μκ³ λΉμ¦λμ€ λ‘μ§μ μ§μ€ν μ μλ€λ μ₯μ μ΄ μμ΅λλ€.
μλμ²λΌ μ¬μ©λ©λλ€.
// μΈν°νμ΄μ€ λ 벨μ μ€μ
@Transactional
public interface TestService {
// μΈν°νμ΄μ€ λ©μλ λ 벨μ μ€μ
@Transactional
public void add();
}
// ν΄λμ€ λ 벨μ μ€μ
@Transactional
public class TestServiceImpl {
// ν΄λμ€ λ©μλ λ 벨μ μ€μ
@Transactional
public void add() {
...
}
}
μ μμμ²λΌ μ΄ λ€κ°μ§ 컨ν μ€νΈ(μΈν°νμ΄μ€, μΈν°νμ΄μ€ λ©μλ, ν΄λμ€, ν΄λμ€ λ©μλ)μμ νμ©ν μ μμ΅λλ€.
μ΄ λ μ μ© μ°μ μμλ ν΄λμ€ λ©μλ -> ν΄λμ€ -> μΈν°νμ΄μ€ λ©μλ -> μΈν°νμ΄μ€ μμ΄ λ©λλ€.
νΈλμμ μ ν μμ±
Java Spring νκ²½μ΄ μ΅μμΉ μμ μ μκ²λ μμν κ°λ μ΄μμ΅λλ€.
λ€λ§ μ΄λ€ κ°λ μΈμ§ κ°μ μ‘κ³ λλ μ½λμ μ¬μ¬μ©μ±μ λμ¬μ£Όλ μ’μ κΈ°λ₯μ΄λΌλ μκ°μ΄ λ€μμ΅λλ€.
νΈλμμ μ ν μμ±μ΄λ, μ΄λ―Έ μμ±λ νΈλμμ λ΄λΆμμ λ€μ @Transactional μ΄λ Έν μ΄μ μ΄ λΆμ λ©μλλ₯Ό νΈμΆν λ μ΄λ»κ² μ²λ¦¬ν μ§μ λν κ°λ μ λλ€.
λ§μ½ μ΄λ―Έ @Transactional μ΄λ Έν μ΄μ μ λΆμ¬λ DML μλΉμ€ λ‘μ§ Aκ° μλ€κ³ κ°μ ν©μλ€. μ΄ λ λ€λ₯Έ μλΉμ€μμ ν΄λΉ μλΉμ€μ DML λ‘μ§μ μ¬λ¬λ² νΈμΆνκ³ νλ²μ΄λΌλ μ€ν¨νμ κ²½μ° λͺ¨λ DMLμ λ‘€λ°±νκ³ μΆμ μν©μ΄ λ°μνμ λ, μμ νΈλμμ μ΄ Aμ λ‘μ§μ μ νλμ§ μλλ€λ©΄ λ νΈλμμ μ μ¬μ€μ λ 립λ νΈλμμ μΌλ‘ μ¬κ²¨μ§ν λ νλ²μ λ‘€λ°±ν μκ° μμ΄μ§κ³ μ΄λ‘ μΈν΄ Aμ λ‘μ§μ 볡λΆν΄μΌνλ μν©μ΄ λ°μν©λλ€.
νΈλμμ μ ν μ€μ μ ν΅ν΄ μ΄λ¬ν λ¬Έμ λ₯Ό μ°μνκ² ν΄κ²°ν μ μμ΄μ§λ κ²μ λλ€.
μ ν μμ±μΌλ‘λ λ€μν μ΅μ μ μ€ μ μλλ°, λͺκ°λ§ μΆλ¦¬λ©΄ μλμ κ°μ΅λλ€.
- REQUIRED: μ΄λ―Έ μμ±λ νΈλμμ μ΄ μλ€λ©΄ κ·Έμ μ°Έμ¬νκ³ , κ·Έλ μ§ μλ€λ©΄ μλ‘ νΈλμμ μμ±
- REQUIRES_NEW: μ΄λ―Έ μμ±λ νΈλμμ μ μ 무μ κ΄λ ¨ μμ΄, νμ μλ‘μ΄ νΈλμμ μμ±
- SUPPORTS: μ΄λ―Έ μμ±λ νΈλμμ μ΄ μλ€λ©΄ κ·Έμ μ°Έμ¬νκ³ , κ·Έλ μ§ μλ€λ©΄ νΈλμμ μμ΄ μ€ν
λ λ§μ μ΅μ μ μλ λ§ν¬μμ νμΈν μ μμ΅λλ€.
https://www.baeldung.com/spring-transactional-propagation-isolation#transaction-propagations
λΉμ¦λμ€ λ‘μ§μ λͺ μμ @Transactionalμ λΆμ¬μ£Όλ μ΄μ
μλ‘ μμ μΈκΈν μ½λ 리뷰μμ μ λ, μ λΉμ¦λμ€ λ‘μ§μ @Transactional μ΄λ Έν μ΄μ μ λΆμ¬μ£Όμ§ μμλλ μ§λ¬Έμ λ°μμ΅λλ€.
κ·Έ λ μ λ Όλ¦¬λ μλμ κ°μμ΅λλ€.
- λ¨μΌ 쿼리λ μ΄μ°¨νΌ DB μλ² μΈ‘μμ νλμ νΈλμμ μΌλ‘ μμ©νλλ°, κ΅³μ΄ νΈλμμ μ λͺ μμ μΌλ‘ μ²λ¦¬ν΄μ€ νμκ° μλλ
- μλΉμ€ λ‘μ§ μ 체μ μ μ©νλ κ²μ λΆνμνκ² νΈλμμ μ κΈΈμ΄λ₯Ό κΈΈκ² λ§λλ κ² μλκ°
- μ¬λ¬ μΏΌλ¦¬κ° νλμ μμ λ¨μλ‘ μμ©ν΄μΌν λμ, μλ² μΈ‘μμ μΆκ°μ μΈ κ²μ¦μ ν΅ν΄ λͺ μμ μΌλ‘ λ‘€λ°±ν΄μΌνλ μν©μ΄ μλλΌλ©΄ κ΅³μ΄...?
μ΄ κΈμ μμ±νκ³ μλ μ΄ μμ μ μκ°μ΄ λ°λμκΈ° λλ¬Έμ μλ¬Έμλ΅νλ μμΌλ‘ μμ λ Όλ¦¬λ₯Ό λ°λ°νκ² μ΅λλ€.
λ¨μΌ 쿼리λ μ΄μ°¨νΌ DB μλ² μΈ‘μμ νλμ νΈλμμ μΌλ‘ μμ©νλλ°, κ΅³μ΄ νΈλμμ μ λͺ μμ μΌλ‘ μ²λ¦¬ν΄μ€ νμκ° μλλ
μ΄ λ Όλ¦¬λ₯Ό νΌμΉ λΉμ μ κ° λͺ°λλ μ¬μ€μ, JpaRepository μΈν°νμ΄μ€λ₯Ό μμν Repositoryμμ μ΄λ£¨μ΄μ§λ κΈ°λ³Έμ μΈ DA μμ μ λͺ μμ μΌλ‘ μ λΆ @Transactionalμ΄ λΆμ΄μλ€λ μ μ λλ€.
μ΄λ JpaRepositoryμ μ€μ§μ μΈ κ΅¬νμ²΄μΈ SimpleJpaRepository(springframework.data.jpa.repository.support.SimpleJpaRepository) ν΄λμ€λ₯Ό 보면 μ μ μλλ°, μ΄μ ꡬνλ DAμ© λ©μλ(ex. findAll, save λ±)μλ λͺ¨λ @Transactionalμ΄ μ΄λ―Έ λ¬λ €μμ΅λλ€.
λ°λΌμ μ κ° DB μλ² μΈ‘μμ νλμ νΈλμμ μΌλ‘ μλ μ·¨κΈλ κ²μ΄λΌκ³ μ΄μΌκΈ°ν λ΄μ©μ μ΄λ―Έ, λ Όμμ μ μ λΆν° μλͺ»λ κ²μ λλ€. μ κ° @Transactionalμ κ±Έλ λ§λ , μ ν리μΌμ΄μ λ 벨μ λͺ μμ μΈ νΈλμμ μ μμλ©λλ€.
μλΉμ€ λ‘μ§ μ 체μ μ μ©νλ κ²μ λΆνμνκ² νΈλμμ μ κΈΈμ΄λ₯Ό κΈΈκ² λ§λλ κ² μλκ°
νμ νΈλμμ μ΄ μμ ν¬κΈ°λ₯Ό μ μ§νλ κ²μ μ€μν©λλ€. μλνλ©΄ νΈλμμ μ΄ μμνκ³ μ»€λ°λκΈ°κΉμ§ μ€λ 걸리λ μν©μ΄ μ¦λ€λ©΄ DB μΈ‘ μ±λ₯μ μ μν₯μ μ€ μ μκΈ° λλ¬Έμ λλ€. (MVCCκ° μλ€κ³ ν΄λ, μ΄λ₯Ό μν΄ DB μλ² μΈ‘μμ μ μ§ν΄μΌνλ 리μμ€λ‘ μΈν΄ μ μν₯μ μκΈΈ μ λ°μ μλ€.)
μ΄ λ¬Έμ λ‘ μΈν΄ μ‘°κΈ κ³ λ―Όμ ν΄λ΄€λλ°, μ λλ¦λλ‘ λ΄λ¦° κ²°λ‘ μ μΌλ°μ μΈ κ²½μ°μμ λ¬Έμ μλ€λ κ²μ λλ€. μ΄ μν©μμ λ±μ₯νλ μΌλ°μ μΈ μμλ μλμ κ°μ΅λλ€.
- νΈλμμ Start
- μ¬μ©μ λ°μ΄ν° κ²μ¦
- DML μμ²
- μΈλΆ API μμ²(ex. μ΄λ©μΌ λ°μ‘ λ±)
- Commit
κ·Έλ¦¬κ³ μ λ‘μ§λ€μ κ°λ¨ν UserServiceμμ μ΄λ€ ν λ©μλμ μλ λ°©μμ΄λΌ κ°μ ν©μλ€. μ΄ λ μ¬λ°λ₯Έ νΈλμμ κ²½κ³ μ€μ μ μμλ μλμ²λΌ κΈ°μ λκ³€ ν©λλ€.
- μ¬μ©μ λ°μ΄ν° κ²μ¦
- νΈλμμ Start
- DML μμ²
- Commit
- μΈλΆ API μμ²(ex. μ΄λ©μΌ λ°μ‘ λ±)
νμ€ν μμ μ λ³΄λ€ λ λμ보μ λλ€. κ·Έλ°λ° μ΄ κ²½μ°, μ μΈμ νΈλμμ μ ν΅ν΄μ UserServiceμμ ꡬννλκ² μ΄λ €μμ§λλ€. κ·Έλ λ€λ©΄ νλ‘κ·Έλλ° λ°©μ νΈλμμ μΌλ‘ νμ΄μΌν κΉμ?
μ κ° μ΄ μ½λλ₯Ό 리뷰νλ μν©μ΄ μ¨λ€λ©΄, 그보λ€λ UserServiceμ μ± μμ΄ κ³Όλνλ€κ³ ν κ² κ°μ΅λλ€. μ μ΄μ UserServiceκ° λ§λ ν μ± μμ ΈμΌνλ λΆλΆμ΄ λ°λ‘ μμ ν νΈλμμ μΌλ‘ λνλ λ‘μ§μ΄ μλκΉ νꡬμ. κ·Έλ¦¬κ³ μ μ 체 λ‘μ§μ LoginFacade κ°μ κ°μ²΄λ₯Ό μμ±νμ¬ κ±°κΈ°μ μ± μμ λΆμ¬νλ μμΌλ‘ μμ ν κ² κ°μ΅λλ€.
κ·Έλ¦¬κ³ μ΄λ₯Ό μ‘°κΈ νμ₯ν΄μ, μ λ§ν κ²½μ°μμ μλΉμ€ λ μ΄μ΄μ μ μΈμ νΈλμμ μ κ±Έμ΄μ€λ€κ³ ν΄λ μ±λ₯ μ λ¬Έμ κ° μμΌλ¦¬λΌ κ²°λ‘ μ§μμ΅λλ€.
κ·Έλ¦¬κ³ μ΄ κ²°λ‘ μ ν΅νλ©΄ λ§μ§λ§ 3λ²μ§Έ λ Όλ¦¬λ λ°λ°μ΄ κ°λ₯ν©λλ€.
μ¬λ¬ μΏΌλ¦¬κ° νλμ μμ λ¨μλ‘ μμ©ν΄μΌν λμ, μλ² μΈ‘μμ μΆκ°μ μΈ κ²μ¦μ ν΅ν΄ λͺ μμ μΌλ‘ λ‘€λ°±ν΄μΌνλ μν©μ΄ μλλΌλ©΄ κ΅³μ΄...?
κ·Έλμ λͺ μμ μΌλ‘ λΆμ¬μΌ νλ μ΄μ λ?
μ± μμ μ λΆλ¦¬ν μλΉμ€ λ μ΄μ΄λΌλ©΄, κ²°κ΅ ν΄λΉ λ μ΄μ΄μμ μννλ λΉμ¦λμ€ λ‘μ§λ€μ DBμ μνμ ν° κ΄λ ¨μ΄ μμ κ°λ₯μ±μ΄ ν½λλ€. λ°λΌμ λͺ μμ μΌλ‘ @Transactional(readonly = true) μ΄λ Έν μ΄μ μ λΆμ¬μ£Όλ κ²μ μ€μ λ‘ νΈλμμ μ΄ νμν κ²½μ°μμ μ€μν κ°λ₯μ±μ ν¬κ² μ€μ¬μ€ κ²μ λλ€. (μμμ μ΄μΌκΈ°νλ―μ΄ λΆμΈλ€κ³ ν¬κ² λ¬Έμ κ° λλ κ²λ μλꡬμ γ γ )
β» 2024.02.04 μΆκ°
@Transactionalμ΄ μλΉμ€ λ μ΄μ΄μ μμ κ²½μ°, μμμ± μ»¨ν μ€νΈμ μν°ν° setterλ₯Ό ν΅ν μμ°μ€λ¬μ΄ μ ν리μΌμ΄μ - DB λκΈ°νκ° λΆκ°λ₯νκ³ λͺ μμ μΌλ‘ μμμ± μ»¨ν μ€νΈλ₯Ό κ΄λ¦¬ν΄μ£Όμ΄μΌ νλ λ¬Έμ λ μμ΅λλ€.
νκΈ°
νΈλμμ μ μ λ€λ΄ν κ°λ λ€(κ³ λ¦½ λ 벨 κ°μ)μ μλμ μΌλ‘ λ€λ£¨μ§ μμκ³ μ κ° λͺ°λλ μλ° μͺ½ μ΄μΌκΈ°λ₯Ό μμ£Όλ‘ λ€λ€μ΅λλ€. κΈμ μμ±νλ©΄μ Springμ DB Access ννΈλ₯Ό κ°μ΄ 곡λΆν λλμΈλ°, 보면 λ³Όμλ‘ μ λͺ¨λ₯΄λ λΆλΆλ€μ΄ κ³μ νμ΄λμμ μ’ λΉν©... (νΉν μμμ± μ»¨ν μ€νΈ κ°μ)
μ°Έκ³ λ¬Έμ
ν λΉμ μ€νλ§ 3.1 - μ΄μΌλ―Ό μ