λ³Έλ¬Έ λ°”λ‘œκ°€κΈ°

study

@Transactional(readOnly=true)

@Transaction(read only=true) λ₯Ό μ™œ μ“ΈκΉŒ?

λ¨Όμ €, νŠΈλžœμž­μ…˜μ΄ ν•„μš”ν•œ 이유

μ–΄λ–€ μ˜ˆμƒμΉ˜ λͺ»ν•œ μƒν™©μ—μ„œ μ˜ˆμ™Έ, 였λ₯˜κ°€ λ°œμƒν•˜μ—¬ 데이터 뢀정합이 λ°œμƒν•˜λŠ” 경우, 데이터 원상 볡ꡬλ₯Ό ν•΄μ•Όν•œλ‹€.

이 λ•Œ 데이터 원상볡ꡬλ₯Ό μœ„ν•΄ νŠΈλžœμž­μ…˜μ΄ ν•„μš”ν•˜λ‹€.

데이터 λ² μ΄μŠ€λŠ” μˆ˜ν–‰ 내역을 λ‘œκ·Έμ— μ €μž₯ν•΄ λ‘λŠ”λ°, 이λ₯Ό μ΄μš©ν•΄ νŠΈλžœμž­μ…˜μ„ μ§€μ›ν•œλ‹€.

  • DB에 반영된 λ‚΄μš©μ„ μž¬λ°˜μ˜ν•˜κΈ° μœ„ν•œ Redo log
  • μˆ˜ν–‰μ„ μ‹€νŒ¨ν•΄ μ΄μ „μ˜ μƒνƒœλ‘œ λ˜λŒλ¦¬λŠ” Undo log

readOnly=true μ„€μ •μ‹œ Application μΈ‘λ©΄

  • DataSourceTranscationManager.java

    SET TRANSACTION READ ONLY λŠ” Oracle, MySQL, Postresμ—μ„œ μ μš©λ©λ‹ˆλ‹€. λ‹€λ₯Έ 데이터 λ² μ΄μŠ€μ—μ„œλ„ μ μš©ν•˜κ³  μ‹Άλ‹€λ©΄ λ©”μ„œλ“œ μž¬μ •μ˜λ₯Ό ν•΄μ•Όν•©λ‹ˆλ‹€.

    • readOnly=true λ©΄ Slave DB, falseλ©΄ Master DB 에 μ ‘μ†ν•˜λ„λ‘ μ„€μ •ν•  수 μžˆλ‹€.
  • HibernateTransactionManager.java

    session.setFlushMode(FlushMode.MANUAL);

    • FlushModeλ₯Ό MANUAL둜 λ³€κ²½ν•΄μ„œ Dirty checking 을 μƒλž΅ν•˜κ²Œ ν•΄μ€€λ‹€.

      β†’ μ—”ν‹°ν‹° μŠ€λƒ…μƒ·μ„ λ§Œλ“€μ§€ μ•ŠλŠ”λ‹€.

read only= true μ„€μ •μ‹œ Database μΈ‘λ©΄

SET TRANSACTION READ ONLY : ν˜„μž¬μ˜ νŠΈλžœμž­μ…˜μ„ ReadOnly둜 μ„€μ •ν•œλ‹€.

1. MySQL

  • SELECT 문에 λŒ€ν•΄μ„œλ§Œ κΈ°λŠ₯을 μ§€μ›ν•œλ‹€.

    • read-only μ„€μ •ν•œ μƒνƒœμ—μ„œ Insert(update,delete)ν•  λ•Œμ— μ˜ˆμ™Έκ°€ λ°œμƒν•œλ‹€.
  • Read Only νŠΈλžœμž­μ…˜μ— λŒ€ν•΄μ„œλŠ” νŠΈλžœμž­μ…˜ IDκ°€ λΆ€μ—¬λ˜μ§€ μ•ŠλŠ”λ‹€. β†’ νŠΈλžœμž­μ…˜ ID 섀정에 λŒ€ν•œ μ˜€λ²„ν—€λ“œκ°€ μ—†λ‹€. (μ„±λŠ₯ν–₯상)

  • λ³„λ„μ˜ μŠ€λƒ…μƒ·μ„ 톡해 데이터λ₯Ό μ‘°νšŒν•˜κΈ° λ•Œλ¬Έμ—, 데이터 일관성을 보μž₯ν•œλ‹€.

2. Oracle

  • SELECT ꡬ문만 μ§€μ›ν•œλ‹€.
  • νŠΈλžœμž­μ…˜μ΄ μ‹œμž‘λ˜κΈ° 이전에 μ»€λ°‹λœ λ°μ΄ν„°λ§Œ μ ‘κ·Όν•  수 있고, νŠΈλžœμž­μ…˜μ΄ μ‹€ν–‰λ˜λŠ” λ™μ•ˆ μ»€λ°‹λ˜λŠ” λ°μ΄ν„°λŠ” 결과에 λ°˜μ˜λ˜μ§€ μ•ŠλŠ”λ‹€.
  • 즉, ν•΄λ‹Ή νŠΈλžœμž­μ…˜ λ‚΄μ—μ„œ 일관적인 데이터λ₯Ό 얻도둝 보μž₯ν•˜λŠ” μš©λ„λ‹€.
  • μ„±λŠ₯ μ΄μ λ§Œμ„ μœ„ν•¨μ΄ μ•„λ‹ˆλ‹€.

3. PostgreSQL

  • SELECT λ₯Ό μ œμ™Έν•œ DDL, DML, DCL 은 λ™μž‘ν•˜μ§€ μ•ŠλŠ”λ‹€.
  • Read/Write 속성과 μ„±λŠ₯ 차이λ₯Ό 가지지 μ•ŠλŠ”λ‹€. 즉 μ½κΈ°μ „μš©μœΌλ‘œ μ΅œμ ν™”λ₯Ό ν•  수 μ—†λ‹€.
  • ν–‰ λ‹¨μœ„κ°€ μ•„λ‹Œ νŠΈλžœμž­μ…˜ λ‹¨μœ„μ˜ μ œμ•½μ‘°κ±΄ 검증 처리λ₯Ό μ μš©ν–ˆμ„ λ•Œ(Deffered 속성 적용), SERIALIZABLE μ΄κ±°λ‚˜ READ ONLY λ₯Ό μ‚¬μš©ν•˜κ²Œ λ˜μ–΄ λ‚΄λΆ€ νŠœν”Œμ΄ μˆ˜μ •λ˜μ§€ μ•ŠλŠ” ν•œ μ•ˆμ „ν•œ λ™μž‘μ„ μ§€μ›ν•˜λŠ” μš©λ„λ‘œ μ‚¬μš©λœλ‹€.
  • 즉 λ™μ‹œμ„± μ œμ–΄λ₯Ό μœ„ν•œ 섀정이닀.
  • νŠΈλžœμž­μ…˜ IDλ₯Ό 일반적인 IDκ°€ μ•„λ‹Œ 가상 ID둜 μ œκ³΅ν•˜μ—¬, μ‹€μ œλ‘œλŠ” νŠΈλžœμž­μ…˜ ID μˆ˜κ°€ μ€„μ–΄λ“€κ²Œ λ˜λ―€λ‘œ μ„±λŠ₯이 κ°œμ„  될 μˆ˜λ„ μžˆλ‹€.

DBμ—μ„œ readOnly=true 을 μ‚¬μš©ν•˜λŠ” 이유

  1. Lock을 μ μš©ν•  ν•„μš”κ°€ μ—†λ‹€.

    readOnly νŠΈλžœμž­μ…˜μ€ 데이터에 λŒ€ν•΄ Lock을 걸지 μ•Šμ•„λ„ μ ‘κ·Όν•  수 μžˆλŠ” 데이터(μŠ€λƒ…μƒ·, νŠœν”Œ λ“±)κ°€ λ³€κ²½λ˜μ§€ μ•Šκ³  데이터 일관성을 보μž₯ν•  수 μžˆλ‹€.

  2. μ„±λŠ₯상 이점이 μžˆλ‹€.

    νŠΈλžœμž­μ…˜ ID 섀정에 λŒ€ν•œ μ˜€λ²„ν—€λ“œλ₯Ό μ€„μ΄κ±°λ‚˜, λ°œμƒν•˜μ§€ μ•ŠκΈ° λ•Œλ¬Έμ— μ„±λŠ₯상 이점이 μžˆλ‹€.

Conclusion

데이터 일관성을 보μž₯ν•˜λ©° μΆ”κ°€ μž‘μ—…μ— λŒ€ν•œ μ˜€λ²„ν—€λ“œλ₯Ό 쀄여 μ„±λŠ₯을 ν–₯μƒμ‹œν‚¬ 수 μžˆλ‹€.

  1. 일반적으둜 JPA(hibernate)λ₯Ό μ“°λŠ” 경우 Dirty Checking을 ν•˜μ§€ μ•ŠμŒμœΌλ‘œμ¨ μŠ€λƒ…μƒ·μ„ μ°λŠ” μ˜€λ²„ν—€λ“œλ₯Ό ν”Όν•  수 μžˆλ‹€.(μ„Έμ…˜ λ©”λͺ¨λ¦¬ 곡간 μ ˆμ•½, ν”ŒλŸ¬μ‹œ μž‘μ—… κ°μ†Œ) β†’ μ„±λŠ₯ ν–₯상
  2. DB μΈ‘λ©΄μ—μ„œ νŠΈλžœμž­μ…˜ ID 에 λŒ€ν•œ μ˜€λ²„ν—€λ“œλ₯Ό 쀄일 수 μžˆλ‹€.

Ref

https://lob-dev.tistory.com/entry/DBMS-별-Transaction-Read-Only에-λŒ€ν•œ-λ™μž‘-방식-1
https://www.inflearn.com/questions/7185
https://sg-choi.tistory.com/598
https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/jdbc/datasource/DataSourceTransactionManager.html
https://thorben-janssen.com/read-only-query-hint/