- DB νΈλμμ
μ΄λ, DB κ΄λ¦¬ μμ€ν
λλ μ μ¬ν μμ€ν
μμμ μνΈμμ©μ λ¨μμ΄λ€.
- λ¨μ : λ μ΄μ μͺΌκ°μ§ μ μλ μ΅μμ μ°μ°
- κ²°μ μμ
μ νΈλμμ
μμλ‘ λ€ κ²½μ°
- κ²°μ λ λ€λ₯Έ μ¬λκ³Ό λ 립μ μΌλ‘ μ΄λ£¨μ΄μ§λ©° κ³Όμ μ€μ λ€λ₯Έ μ°μ°μ΄ λΌμ΄λ€ μ μλ€. μ€λ₯κ° μκΈ΄ κ²½μ° μ°μ°μ μ·¨μνκ³ μλλλ‘ λλλ¦°λ€. μ±κ³΅ν κ²½μ° κ²°κ³Όλ₯Ό λ°μνλ€.
- νΈλμμ μ μμΉ : ACID (μμμ±, μΌκ΄μ±, κ³ λ¦½μ±, μ§μμ±)
- ν΄λμ€λ λ©μλμ λΆμΌ κ²½μ°, ν΄λΉ λ²μ λ΄ λ©μλκ° νΈλμμ
μ΄ λλλ‘ λ³΄μ₯ν΄μ€λ€.
- μ μΈμ νΈλμμ : μ§μ κ°μ²΄λ₯Ό λ§λ€ νμ μμ΄ μ μΈλ§μΌλ‘λ κ΄λ¦¬λ₯Ό μ©μ΄νκ² ν΄μ€
- μμ μ½λ
@RequiredArgsConstruct
@Service
public class MemberService {
private final MemberRepository memberRepository;
@Transactional(readOnly = true)
public List<MemberResponseEntity> getMembers() {
return bookRepository.findAll();
}
}getMembers()λ©μλλ μλμ κ°μ μμ±μ κ°μ§λ€.- μ°μ°μ΄ κ³ λ¦½λμ΄ λ€λ₯Έ μ°μ°κ³Όμ νΌμ μΌλ‘ μΈν΄ μλͺ»λ κ°μ κ°μ Έμ€λ κ²½μ°κ° λ°©μ§λλ€.
- μ°μ°μ μμμ±μ΄ 보μ₯λμ΄ μ°μ°μ΄ λμ€μ μ€ν¨ν κ²½μ° λ³κ²½μ¬νμ΄ λ°μλμ§ μλλ€.
- λ°λΌμ ν΄λΉ λ©μλκ° μ€νλλ λμ€ λ©μλ κ°μ μμ λλ μμ νλ €λ μλκ° λ€μ΄μλ κ°μ μ λ’°μ±μ΄ 보μ₯λλ€.
- @Transactional μ΄λ
Έν
μ΄μ
μ΄ ν΄λμ€ λλ λ©μλμ λΆμ κ²½μ° Springμ΄ ν΄λΉ λ©μλμ λνμ¬ νλ‘μλ₯Ό λ§λ λ€.
- νλ‘μ ν¨ν΄
- μ΄λ€ μ½λλ₯Ό κ°μΈλ©΄μ μΆκ°μ μΈ μ°μ°μ μννλλ‘ κ°μ νλ ν¨ν΄
- νΈλμμ μ κ²½μ° μμκ³Ό μ°μ° μ’ λ£ μμ μ»€λ° κ³Όμ μ΄ νμνλ―λ‘, νλ‘μλ₯Ό μμ±ν΄ ν΄λΉ λ©μλμ μλ€μ νΈλμμ μ μμκ³Ό λμ μΆκ°νλ κ²
- λν Spring 컨ν
μ΄λλ νΈλμμ
λ²μμ μμμ± μ»¨ν
μ€νΈ μ λ΅μ κΈ°λ³ΈμΌλ‘ μ¬μ©νλ€.
- μλΉμ€ ν΄λμ€μμ @Transactional μ΄λ Έν μ΄μ μ μ¬μ©νλ©΄, ν΄λΉ μ½λ λ΄μ λ©μλλ₯Ό νΈμΆν λ μμμ± μ»¨ν μ€νΈκ° μκΈ΄λ€λ μλ―Έ
isolation- λμμ μ¬λ¬ μ¬μ©μκ° λ°μ΄ν°μ μ κ·Όν λ μ΄λκΉμ§ νμ©ν μ§μ λνμ¬ μ νλ μ΅μ
- νΈλμμ μ 격리 μμ€κ³Ό λ°μ΄ν°μ μΌκ΄μ±μ λΉλ‘
- @Transactionalμμλ 5κ°μ§
isolationμ΅μ μ 곡DEFAULT- κΈ°λ³Έ 격리 μμ€
READ_UNCOMMITTED- ν νΈλμμ μ΄ μ²λ¦¬ μ€μΈ 컀λ°λμ§ μμ λ°μ΄ν°λ₯Ό λ€λ₯Έ νΈλμμ μ΄ μ κ·Ό κ°λ₯νλλ‘ ν¨
- DBμ 컀λ°λμ§ μμ, μ‘΄μ¬νμ§ μλ λ°μ΄ν°λ₯Ό μ½λ νμμ Dirty Read λΌκ³ ν¨
- Dirty Readκ° κ°λ₯νκΈ° λλ¬Έμ μλͺ»λ λ°μ΄ν°λ₯Ό μ½μ μλ μμ
READ_COMMITTED- 컀λ°λ λ°μ΄ν°λ§ μ κ·Ό κ°λ₯νλλ‘ ν¨
- Non-Repeatable Read νμμ΄ λ°μν μ μμ
- νΈλμμ μμ μ‘°νν λ°μ΄ν°κ° νΈλμμ μ΄ λλκΈ° μ μ λ€λ₯Έ νΈλμμ μ μν΄ λ³κ²½λλ©΄ λ€μ μ½μμ λ λ€λ₯Έ κ°μ΄ μ½νλ©° λ°μ΄ν°κ° λΆμΌμΉκ° λ°μνλ νμ
REPEATABLE_READ- νλμ νΈλμμ μ νλμ μ€λ μ·λ§ μ¬μ©νλλ‘ ν¨
- A νΈλμμ μ΄ μμνκ³ μ²μ μ‘°νν λ°μ΄ν°μ μ€λ μ·μ μ μ₯, μ΄ν λμΌν 쿼리λ₯Ό νΈμΆνλ©΄ μ€λ μ·μμ λ°μ΄ν°λ₯Ό κ°μ Έμ΄
- Phantom Read νμμ΄ λ°μν μ μμ
- λ€λ₯Έ νΈλμμ μμ μνν μμ μ μν΄ μ보μλ λ°μ΄ν°κ° 보μ΄λ νμ
SERIALIZABLE- κ°μ₯ λ¨μνκ³ μ격ν 격리 μμ€
- μμ°¨μ μΌλ‘ νΈλμμ μ μ§νμν€λ©° μ½κΈ° μμ μλ μ κΈμ κ±Έμ΄ μ¬λ¬ νΈλμμ μ΄ λμμ κ°μ λ°μ΄ν°μ μ κ·Όνμ§ λͺ»νκ² ν¨
- κ°μ₯ μμ νμ§λ§ μ±λ₯ μ νκ° λ°μνκΈ° λλ¬Έμ κ·Ήλμ μμ μ±μ νμλ‘ νμ§ μμ κ²½μ° μμ£Ό μ¬μ©νμ§ μμ
propagation- νμ¬ μ§νμ€μΈ νΈλμμ (λΆλͺ¨ νΈλμμ ) μ΄ μ‘΄μ¬ν λ μλ‘μ΄ νΈλμμ λ©μλλ₯Ό νΈμΆν κ²½μ° μ΄λ€ μ μ± μ μ¬μ©ν μ§ μ μνλ μμ±
- @Transactionalμμλ 7κ°μ§
propagationμ΅μ μ 곡REQUIRED- κΈ°λ³Έ κ°μΌλ‘, λΆλͺ¨ νΈλμμ μ΄ μ‘΄μ¬ν κ²½μ° μ°Έμ¬νκ³ μλ κ²½μ° μ νΈλμ Ήμ μμ
SUPPORTS- λΆλͺ¨ νΈλμμ μ΄ μ‘΄μ¬ν κ²½μ° μ°Έμ¬νκ³ μλ κ²½μ° non-transactonal μνλ‘ μ€ν
MANDATORY- λΆλͺ¨ νΈλμμ μ΄ μ‘΄μ¬ν κ²½μ° μ°Έμ¬νκ³ μλ κ²½μ° μμΈ λ°μ
REQUIRES_NEW- λΆλͺ¨ νΈλμμ μ 무μνκ³ λ¬΄μ‘°κ±΄ μλ‘μ΄ νΈλμμ μ΄ μμ±
NOT_SUPPORTED- non-transactional μνλ‘ μ€ννλ©° λΆλͺ¨ νΈλμμ μ΄ μ‘΄μ¬νλ κ²½μ° μΌμμ μ§
NEVER- non-transactional μνλ‘ μ€ννλ©° λΆλͺ¨ νΈλμμ μ΄ μ‘΄μ¬νλ κ²½μ° μμΈ λ°μ
NESTED- λΆλͺ¨ νΈλμμ κ³Όλ λ³κ°λ‘ μ€μ²©λ νΈλμμ μμ±
- λΆλͺ¨ νΈλμμ μ 컀λ°κ³Ό λ‘€λ°±μλ μν₯μ λ°μ§λ§ μμ μ 컀λ°κ³Ό λ‘€λ°±μ λΆλͺ¨ νΈλμμ μ μν₯ μ£Όμ§ μμ
- λΆλͺ¨ νΈλμμ
μ΄ μ‘΄μ¬νμ§ μλ κ²½μ° μλ‘μ΄ νΈλμμ
μμ± (
REQUIRED) - DBκ° SAVEPOINTλ₯Ό μ§μν΄μΌ μ¬μ© κ°λ₯ (Oracle)
JpaTransactionManagerμμλ μ§μνμ§ μμ
readOnly- κΈ°λ³Έκ°μ
falseλ©°trueλ‘ μΈν νλ κ²½μ° νΈλμμ μ μ½κΈ° μ μ©μΌλ‘ λ³κ²½ν¨ - μ±λ₯ ν₯μμ μν΄ μ¬μ©νκ±°λ μ½κΈ° μΈ λ€λ₯Έ λμμ λ°©μ§νκΈ° μν΄ μ¬μ©νκΈ°λ ν¨
- κΈ°λ³Έκ°μ
rollbackFor- μ¬μ©λ²:
@Transactional(rollbackFor = {IOException.class, ClassNotFoundException.class}) - μ¬μ© μ
@Transactional(rollbackFor = IOException.class)μ²λΌ Exceptionμ νλλ§ μ§μ νλ€λ©΄ μ€κ΄νΈ μλ΅ κ°λ₯ - νΉμ Exception λ°μ μ λ°μ΄ν°λ₯Ό 컀λ°νμ§ μκ³ λ‘€λ°±νλλ‘ μ€μ
- μ¬μ©λ²:
timeout- μ¬μ©λ²:
@Transactional(timeout = 3) - μ§μ λ μκ° λ΄μ ν΄λΉ λ©μλ μνμ΄ μλ£λμ§ μλ κ²½μ°
JpaSystemExceptionλ°μ JpaSystemExceptionμRuntimeExceptionμ μμλ°κΈ° λλ¬Έμ λ°μ΄ν°λ λ‘€λ°± μ²λ¦¬λ¨- μ΄ λ¨μλ‘ μ§μ ν μ μμΌλ©° -1 κ°μΌλ‘ μ§μ ν κ²½μ° timeoutμ μ§μνμ§ μμ
- μ¬μ©λ²:
- JPAμ μμμ± μ»¨ν
μ€νΈκ° μννλ λ³κ²½ κ°μ§(Dirty Checking)μ κ΄λ ¨μ΄ μλ€.
- λ³κ²½ κ°μ§?
- μμμ± μ»¨ν μ€νΈλ Entity μ‘°ν μ μ΄κΈ° μνμ λν μ€λ μ·μ μ μ₯νλ€.
- νΈλμμ μ΄ Commit λ λ, μ΄κΈ° μνμ μ 보λ₯Ό κ°μ§λ μ€λ μ·κ³Ό Entityμ μνλ₯Ό λΉκ΅νμ¬ λ³κ²½λ λ΄μ©μ λν΄ update query λ‘ μ°κΈ° μ§μ° μ μ₯μμ μ μ₯νλ€.
- κ·Έ ν μΌκ΄μ μΌλ‘ μ°κΈ° μ§μ° μ μ₯μμ μ μ₯λμ΄ μλ SQL queryλ₯Ό flush νκ³ λ°μ΄ν°λ² μ΄μ€μ νΈλμμ μ Commit ν¨μΌλ‘μ, μ°λ¦¬κ° updateμ κ°μ λ©μλλ₯Ό μ¬μ©νμ§ μκ³ λ Entityμ μμ μ΄ μ΄λ£¨μ΄μ§λ€. μ΄λ₯Ό λ³κ²½ κ°μ§λΌκ³ νλ€.
readOnly = trueλ‘ μ€μ νκ² λλ©΄ μ€νλ§ νλ μμν¬λ JPAμ μΈμ νλ¬μ λͺ¨λλ₯Ό μλμΌλ‘ μ€μ ν΄, μ¬μ©μκ° μλμΌλ‘flush()νΈμΆνμ§ μμΌλ©΄ flushκ° μνλμ§ μκ² νλ€.- νΈλμμ
λ΄μμ κ°μ λ‘
flush()λ₯Ό νΈμΆνμ§ μμΌλ©΄, μμ λ΄μμ λν΄ DBμ μ μ©λμ§ μλλ€. - μ΄λ‘ μΈν΄ νΈλμμ Commit μ μμμ± μ»¨ν μ€νΈκ° μλμΌλ‘ flush λμ§ μμΌλ―λ‘ μ‘°νμ©μΌλ‘ κ°μ Έμ¨ Entityμ μμμΉ λͺ»ν μ€λ₯λ₯Ό λ°©μ§ν μ μλ€.
- νΈλμμ
λ΄μμ κ°μ λ‘
- λν
readOnly = trueλ₯Ό μ€μ νκ² λλ©΄ JPAλ ν΄λΉ νΈλμμ λ΄μμ μ‘°ννλ Entityλ μ‘°νμ©μμ μΈμνκ³ λ³κ²½ κ°μ§λ₯Ό μν μ€λ μ·μ λ°λ‘ 보κ΄νμ§ μμΌλ―λ‘ λ©λͺ¨λ¦¬κ° μ μ½λλ μ±λ₯μ μ΄μ λν μ‘΄μ¬νκ² λλ€.
- λ³κ²½ κ°μ§?