๐ŸŽฏ F-lab Java 10์ฃผ์ฐจ ํ•™์Šต ์ปค๋ฆฌํ˜๋Ÿผ

10์ฃผ์ฐจ ์ž๋ฃŒ์˜ ๋ชจ๋“  ํ† ํ”ฝ์„ "์ •๋ฆฌ โ†’ ์ƒˆ ์ฃผ์ œ" ํ๋ฆ„์œผ๋กœ ์žฌ๋ฐฐ์—ดํ•œ ํ•™์Šต ๊ฒฝ๋กœ.
7~9์ฃผ์ฐจ์—์„œ ๋‹ค๋ฃฌ ํŠธ๋žœ์žญ์…˜ยทAOP๋ฅผ ์ •๋ฆฌํ•˜๋ฉด์„œ, ๋นˆ ์ดˆ๊ธฐํ™” ํ•จ์ • ๊ณผ ํŠธ๋žœ์žญ์…˜ ๊ฒฉ๋ฆฌ ์ˆ˜์ค€์ด๋ผ๋Š” ๋‘ ๊ฐ€์ง€ ์ƒˆ ํ† ํ”ฝ์„ ์ถ”๊ฐ€ํ•œ๋‹ค.

๋ถ„๋Ÿ‰์€ 8-9์ฃผ์ฐจ๋ณด๋‹ค ๊ฐ€๋ณ์ง€๋งŒ, ๋ฉด์ ‘ยท์‹ค๋ฌด ์ง๊ฒฐ ํ•จ์ • ๋‘ ๊ฐœ๊ฐ€ ํ•ต์‹ฌ์ด๋‹ค.


๐Ÿ“Š ํ•™์Šต ๊ฒฝ๋กœ ํ•œ๋ˆˆ์— ๋ณด๊ธฐ

[Phase 1] @Import โ€” ์„ค์ • ํด๋ž˜์Šค ๊ฒฐํ•ฉ
   โ†“
[Phase 2] ์Šคํ”„๋ง ํŠธ๋žœ์žญ์…˜ ์ถ”์ƒํ™” ์ •๋ฆฌ (7์ฃผ์ฐจ ๋ณต์Šต+์‹ฌํ™”)
   โ†“
[Phase 3] ์„ ์–ธ์  vs ํ”„๋กœ๊ทธ๋ž˜๋ฐ ๋ฐฉ์‹ + ํ”„๋ก์‹œ ์ ์šฉ (9์ฃผ์ฐจ ๋ณต์Šต+์‹ฌํ™”)
   โ†“
[Phase 4] ๋นˆ ๋ผ์ดํ”„์‚ฌ์ดํด์˜ ํ•จ์ • โ€” @PostConstruct + @Transactional โ˜…
   โ†“
[Phase 5] ํŠธ๋žœ์žญ์…˜ ๊ฒฉ๋ฆฌ ์ˆ˜์ค€ โ€” DB์™€ Spring์˜ ๊ฒฝ๊ณ„ โ˜…

์ด 5 Phase ร— 16 Unit โ€” ์ผ์ •ํ•œ ๋ถ„๋Ÿ‰์˜ ์ •๋ฆฌ ์ฃผ์ฐจ.

โ˜… ํ‘œ์‹œ Phase๋Š” ์ƒˆ๋กœ ๋“ฑ์žฅํ•˜๋Š” ํ•ต์‹ฌ ์ฃผ์ œ ์ด๋ฉฐ ๋ฉด์ ‘ยท์‹ค๋ฌด ์ง๊ฒฐ.

๐Ÿ”— 1~10์ฃผ์ฐจ ํ๋ฆ„ ์ •๋ฆฌ

์ฃผ์ฐจ์ฃผ์ œํ•ต์‹ฌ ๋ณ€ํ™”
1์ฃผ์ฐจOOPยทJVMยทGCยท์ปฌ๋ ‰์…˜ยทI/O ๊ฐœ๋ก ์ž๋ฐ” ํฐ ๊ทธ๋ฆผ
2์ฃผ์ฐจJVM ๋‚ด๋ถ€ยท๋ฐ”์ดํŠธ์ฝ”๋“œยทG1 GC"์–ด๋–ป๊ฒŒ ๋Œ์•„๊ฐ€๋‚˜"
3์ฃผ์ฐจ์ปฌ๋ ‰์…˜ยท์ œ๋„ค๋ฆญยทํ•จ์ˆ˜ํ˜•์ž๋ฐ” ํ‘œํ˜„๋ ฅ
4์ฃผ์ฐจ๋ฉ€ํ‹ฐ์Šค๋ ˆ๋”ฉยท๋™์‹œ์„ฑยทExecutor๋™์‹œ์„ฑ ์ •๋ณต
5์ฃผ์ฐจAtomic + Spring IoC/DI ์ž…๋ฌธ์ž๋ฐ” โ†’ Spring ๋‹ค๋ฆฌ
6์ฃผ์ฐจํ…Œ์ŠคํŠธ + ์›น ์ธํ”„๋ผ + DB ์ ‘๊ทผ ์ง„ํ™”Spring ์‹ค์ „ ํ™˜๊ฒฝ
7์ฃผ์ฐจJPA/ORM + ํŠธ๋žœ์žญ์…˜ ์ถ”์ƒํ™”DB ์ถ”์ƒํ™”์˜ ์ •์ 
8์ฃผ์ฐจํ”„๋ก์‹œ์˜ ์ง„ํ™”AOP ๋ฉ”์ปค๋‹ˆ์ฆ˜ ์ดํ•ด
9์ฃผ์ฐจSpring AOP ์‹ค์ „ + ํŠธ๋žœ์žญ์…˜ ์ „ํŒŒAOP ์‹ค์ „ ํ™œ์šฉ
10์ฃผ์ฐจ (์ง€๊ธˆ)ํŠธ๋žœ์žญ์…˜ ์ •๋ฆฌ + ๋นˆ ๋ผ์ดํ”„์‚ฌ์ดํด ํ•จ์ • + ๊ฒฉ๋ฆฌ ์ˆ˜์ค€ํŠธ๋žœ์žญ์…˜ ํ•™์Šต์˜ ๋งˆ๋ฌด๋ฆฌ

๐Ÿ—“๏ธ ๊ถŒ์žฅ ํ•™์Šต ์ผ์ • (์••์ถ• 5์ผ)

DayPhaseํ•™์Šต ๋ชฉํ‘œ
1์ผ์ฐจPhase 1 + 2@Import + ์Šคํ”„๋ง ํŠธ๋žœ์žญ์…˜ ์ถ”์ƒํ™” ์ •๋ฆฌ
2์ผ์ฐจPhase 3์„ ์–ธ์  vs ํ”„๋กœ๊ทธ๋ž˜๋ฐ + ํ”„๋ก์‹œ ์ ์šฉ
3์ผ์ฐจPhase 4@PostConstruct + @Transactional ํ•จ์ • (โ˜…)
4์ผ์ฐจPhase 5ํŠธ๋žœ์žญ์…˜ ๊ฒฉ๋ฆฌ ์ˆ˜์ค€ (โ˜…)
5์ผ์ฐจ์ข…ํ•ฉ ์ž๊ธฐ ์ ๊ฒ€ + ์‹ค์Šต์ „์ฒด ์ •๋ฆฌ

์—ฌ์œ  ์ผ์ • (7์ผ): Phase 4ยท5์— ๊ฐ +1์ผ. ๊ฒฉ๋ฆฌ ์ˆ˜์ค€์€ ์ง์ ‘ SQL์„ ๋Œ๋ฆฌ๋ฉฐ ์‹œ๊ฐ์ ์œผ๋กœ ์ฒดํ™”ํ•˜๋Š” ๊ฒŒ ํšจ๊ณผ์ .


๐Ÿ“š Phase 1 โ€” @Import: ์„ค์ • ํด๋ž˜์Šค์˜ ๊ฒฐํ•ฉ

๋ชฉํ‘œ: ์—ฌ๋Ÿฌ ์„ค์ • ํŒŒ์ผ๋กœ ๋ถ„๋ฆฌ๋œ ๋นˆ์„ ํ•˜๋‚˜๋กœ ๋ฌถ๋Š” ์ž‘์€ Spring ๋„๊ตฌ๋ฅผ ์ตํžŒ๋‹ค.

Unit 1.1 โ€” @Import์˜ ์—ญํ• 

์„ ์ˆ˜ ์ง€์‹: 5์ฃผ์ฐจ Phase 8 (ApplicationContext)

ํ•ต์‹ฌ ๊ฐœ๋…

๋ฌธ์ œ:

  • ์„ค์ • ํด๋ž˜์Šค๊ฐ€ ๋Š˜์–ด๋‚˜๋ฉด ๊ด€๋ฆฌ ๋ถ€๋‹ด
  • ๋„๋ฉ”์ธ๋ณ„/ํ™˜๊ฒฝ๋ณ„๋กœ ๋ถ„๋ฆฌํ•˜๊ณ  ์‹ถ์Œ

@Import ์˜ ํ•ด๊ฒฐ:

  • ์—ฌ๋Ÿฌ @Configuration ํด๋ž˜์Šค๋ฅผ ํ•œ ๊ณณ์—์„œ ๊ฒฐํ•ฉ
  • ๊ฒฐํ•ฉํ•œ ์„ค์ • ํด๋ž˜์Šค๋ฅผ ApplicationContext์— ๋“ฑ๋กํ•˜๋ฉด ๋ชจ๋“  ๋นˆ์ด ์ž๋™ ๋“ฑ๋ก
@Configuration
class ServiceConfig {
    @Bean
    public GreetingService greetingService() {
        return new GreetingService();
    }
}

@Configuration
class AppConfig {
    @Bean
    public UserService userService() {
        return new UserService();
    }
}

@Configuration
@Import({ServiceConfig.class, AppConfig.class})  // ๊ฒฐํ•ฉ
class MainConfig {}

์ž๊ธฐ ์ ๊ฒ€

  • 8-9์ฃผ์ฐจ์—์„œ @Import(AspectV1.class) ๋ฅผ ๋ณธ ๋งฅ๋ฝ์€?
  • @Import ์™€ @ComponentScan ์˜ ์ฐจ์ด๋Š”? (ํžŒํŠธ: ๋ช…์‹œ์  vs ์ž๋™)

Unit 1.2 โ€” ์‹ค๋ฌด์—์„œ์˜ @Import ํ™œ์šฉ ํŒจํ„ด

์„ ์ˆ˜ ์ง€์‹: Unit 1.1

ํ•ต์‹ฌ ํŒจํ„ด

ํ™˜๊ฒฝ๋ณ„ ์„ค์ • ๋ถ„๋ฆฌ:

@Configuration
@Import({DatabaseConfig.class, SecurityConfig.class, CacheConfig.class})
public class ApplicationConfig {}

ํ…Œ์ŠคํŠธ์šฉ ์„ค์ • ์ถ”๊ฐ€:

@SpringBootTest
@Import(TestConfig.class)  // ํ…Œ์ŠคํŠธ ์ „์šฉ ๋นˆ ์ถ”๊ฐ€
class IntegrationTest {}

์–ธ์ œ @Component ๋Œ€์‹  @Import?:

  • ์ปดํฌ๋„ŒํŠธ ์Šค์บ” ๋Œ€์ƒ ์™ธ๋ถ€์˜ ํด๋ž˜์Šค
  • ์™ธ๋ถ€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์˜ @Configuration ํด๋ž˜์Šค
  • ํ…Œ์ŠคํŠธ์—์„œ๋งŒ ํ™œ์„ฑํ™”ํ•  ๋นˆ

์ž๊ธฐ ์ ๊ฒ€

  • ์™ธ๋ถ€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์˜ ๋นˆ์„ ๋“ฑ๋กํ•  ๋•Œ @ComponentScan์œผ๋กœ๋Š” ์™œ ํ•œ๊ณ„๊ฐ€ ์žˆ๋Š”๊ฐ€?
  • @Import vs @EnableXxx ์–ด๋…ธํ…Œ์ด์…˜์˜ ๊ด€๊ณ„๋Š”? (ํžŒํŠธ: ํ›„์ž๋„ @Import ํ™œ์šฉ)

๐Ÿ“š Phase 2 โ€” ์Šคํ”„๋ง ํŠธ๋žœ์žญ์…˜ ์ถ”์ƒํ™” ์ •๋ฆฌ (7์ฃผ์ฐจ ๋ณต์Šต+์‹ฌํ™”)

๋ชฉํ‘œ: 7์ฃผ์ฐจ์—์„œ ๋‹ค๋ฃฌ PlatformTransactionManager์˜ ๋ณธ์งˆ์„ ๋‹ค์‹œ ์งš๊ณ  Spring Boot์˜ ์ž๋™ ๊ตฌ์„ฑ๊นŒ์ง€ ์ •๋ฆฌํ•œ๋‹ค.

Unit 2.1 โ€” ํŠธ๋žœ์žญ์…˜ ๊ธฐ์ˆ ๋งˆ๋‹ค ๋‹ค๋ฅธ ์ฝ”๋“œ (๋ฌธ์ œ ์ •์˜)

์„ ์ˆ˜ ์ง€์‹: 7์ฃผ์ฐจ Phase 5

ํ•ต์‹ฌ ๋ฌธ์ œ

๊ธฐ์ˆ ๋งˆ๋‹ค ํŠธ๋žœ์žญ์…˜ ์ฝ”๋“œ๊ฐ€ ๋‹ค๋ฆ„:

  • JDBC: connection.setAutoCommit(false) + commit() / rollback()
  • JPA: EntityTransaction.begin() + commit() / rollback()
  • MyBatis: SqlSession ๋‹จ์œ„
  • Hibernate: Session ๋‹จ์œ„

๊ฒฐ๊ณผ:

  • JDBC โ†’ JPA๋กœ ์ „ํ™˜ ์‹œ ๋ชจ๋“  ํŠธ๋žœ์žญ์…˜ ์ฝ”๋“œ ์ˆ˜์ •
  • ๊ธฐ์ˆ  ์ข…์†์„ฑ์ด ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง๊นŒ์ง€ ์นจํˆฌ

โ†’ ์ถ”์ƒํ™” ํ•„์š” = PlatformTransactionManager

์ž๊ธฐ ์ ๊ฒ€

  • 6์ฃผ์ฐจ DataSource ์ถ”์ƒํ™”์˜ ์‚ฌ์ƒ๊ณผ ๊ฐ™์€๊ฐ€?
  • 7์ฃผ์ฐจ์—์„œ ๋ณธ ๋™์ผํ•œ ํ† ํ”ฝ์„ ํ•œ ์ค„๋กœ ์š”์•ฝํ•˜๋ฉด?

Unit 2.2 โ€” PlatformTransactionManager ์ธํ„ฐํŽ˜์ด์Šค์˜ ๋ณธ์งˆ

์„ ์ˆ˜ ์ง€์‹: Unit 2.1

ํ•ต์‹ฌ ์ธํ„ฐํŽ˜์ด์Šค:

public interface PlatformTransactionManager extends TransactionManager {
    TransactionStatus getTransaction(TransactionDefinition definition);
    void commit(TransactionStatus status);
    void rollback(TransactionStatus status);
}

3๊ฐ€์ง€ ๋ฉ”์„œ๋“œ๋งŒ:

  • ์‹œ์ž‘ (getTransaction)
  • ์ปค๋ฐ‹ (commit)
  • ๋กค๋ฐฑ (rollback)

๊ตฌํ˜„์ฒด ๋งคํ•‘:

๋ฐ์ดํ„ฐ ์ ‘๊ทผ ๊ธฐ์ˆ TransactionManager ๊ตฌํ˜„์ฒด
JDBC, JdbcTemplate, MyBatisDataSourceTransactionManager (= JdbcTransactionManager)
Hibernate (์ง์ ‘ ์‚ฌ์šฉ)HibernateTransactionManager
JPAJpaTransactionManager

์ž๊ธฐ ์ ๊ฒ€

  • ์ธํ„ฐํŽ˜์ด์Šค์˜ ๋ฉ”์„œ๋“œ๊ฐ€ ๋‹จ 3๊ฐœ์ธ ์ด์œ ๋Š”? (ํžŒํŠธ: ํŠธ๋žœ์žญ์…˜์˜ ๋ณธ์งˆ)
  • 7์ฃผ์ฐจ์˜ DataSource ์ธํ„ฐํŽ˜์ด์Šค ๋ฉ”์„œ๋“œ ์ˆ˜์™€ ๋น„๊ตํ•˜๋ฉด?

Unit 2.3 โ€” Spring Boot์˜ ์ž๋™ ํŠธ๋žœ์žญ์…˜ ๋งค๋‹ˆ์ € ๋“ฑ๋ก

์„ ์ˆ˜ ์ง€์‹: Unit 2.2

ํ•ต์‹ฌ ๊ฐœ๋…

Spring Boot์˜ ์ž๋™ ๊ตฌ์„ฑ:

  • ํด๋ž˜์ŠคํŒจ์Šค์˜ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์ธ์‹
  • ์ ์ ˆํ•œ TransactionManager๋ฅผ ์ž๋™ ๋นˆ ๋“ฑ๋ก
์˜์กด์„ฑ์ž๋™ ๋“ฑ๋ก
spring-boot-starter-jdbcDataSourceTransactionManager
spring-boot-starter-data-jpaJpaTransactionManager

๊ฐœ๋ฐœ์ž๊ฐ€ ํ•  ์ผ:

  • ์˜์กด์„ฑ๋งŒ ์ถ”๊ฐ€
  • @Transactional ์‚ฌ์šฉ
  • โ†’ ํŠธ๋žœ์žญ์…˜ ๋งค๋‹ˆ์ € ์„ ํƒยท๋“ฑ๋ก ๋ชจ๋‘ ์ƒ๋žต ๊ฐ€๋Šฅ

ILIC ์‚ฌ๋ก€:

  • spring-boot-starter-data-jpa ์‚ฌ์šฉ โ†’ JpaTransactionManager ์ž๋™ ๋“ฑ๋ก
  • ๋ณ„๋„ ์„ค์ • ๋ถˆํ•„์š”

์ž๊ธฐ ์ ๊ฒ€

  • ๋‘ ๊ฐ€์ง€ ๋ฐ์ดํ„ฐ ์ ‘๊ทผ ๊ธฐ์ˆ ์„ ํ•จ๊ป˜ ์“ฐ๋ฉด? (ํžŒํŠธ: ChainedTransactionManager ๋“ฑ)
  • ์ž๋™ ๊ตฌ์„ฑ์ด ์ž˜๋ชป ๋™์ž‘ํ•˜๋ฉด ์–ด๋–ป๊ฒŒ ์ง„๋‹จํ•˜๋Š”๊ฐ€? (ํžŒํŠธ: --debug ์ถœ๋ ฅ)

๐Ÿ“š Phase 3 โ€” ์„ ์–ธ์  vs ํ”„๋กœ๊ทธ๋ž˜๋ฐ ๋ฐฉ์‹ + AOP ์ ์šฉ (9์ฃผ์ฐจ ๋ณต์Šต+์‹ฌํ™”)

๋ชฉํ‘œ: 9์ฃผ์ฐจ์—์„œ ๋ณธ @Transactional์˜ ๋ณธ์งˆ์„ "ํ”„๋ก์‹œ ๋„์ž… ์ „ํ›„ ์ฝ”๋“œ ๋น„๊ต" ๋กœ ๋‹ค์‹œ ํ•œ๋ฒˆ ๋ชป ๋ฐ•๋Š”๋‹ค.

Unit 3.1 โ€” ๋‘ ๊ฐ€์ง€ ํŠธ๋žœ์žญ์…˜ ๊ด€๋ฆฌ ๋ฐฉ์‹

์„ ์ˆ˜ ์ง€์‹: 7์ฃผ์ฐจ Phase 7, 9์ฃผ์ฐจ Phase 10

ํ•ต์‹ฌ ๊ฐœ๋…

๋ฐฉ์‹์ •์˜์žฅ์ ๋‹จ์ 
์„ ์–ธ์  (@Transactional)์–ด๋…ธํ…Œ์ด์…˜ ํ•œ ์ค„ ์„ ์–ธ๋งค์šฐ ๊ฐ„ํŽธํ•จ์ • ๅคš (internal call ๋“ฑ)
ํ”„๋กœ๊ทธ๋ž˜๋ฐ (TransactionTemplate)ํŠธ๋žœ์žญ์…˜ ์ฝ”๋“œ ์ง์ ‘ ์ž‘์„ฑ์„ธ๋ฐ€ํ•œ ์ œ์–ด๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง๊ณผ ๊ฒฐํ•ฉ

ํ”„๋กœ๊ทธ๋ž˜๋ฐ ๋ฐฉ์‹์˜ ํ•œ๊ณ„:

"์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์ฝ”๋“œ๊ฐ€ ํŠธ๋žœ์žญ์…˜์ด๋ผ๋Š” ๊ธฐ์ˆ  ์ฝ”๋“œ์™€ ๊ฐ•ํ•˜๊ฒŒ ๊ฒฐํ•ฉ"

์‹ค๋ฌด ๊ฒฐ๋ก :

"์„ ์–ธ์  ํŠธ๋žœ์žญ์…˜์ด ๊ฑฐ์˜ ํ‘œ์ค€ โ€” ํ”„๋กœ๊ทธ๋ž˜๋ฐ ๋ฐฉ์‹์€ ํŠน์ˆ˜ ์ผ€์ด์Šค์—๋งŒ"

์ž๊ธฐ ์ ๊ฒ€

  • "๊ธฐ์ˆ  ์ฝ”๋“œ์™€์˜ ๊ฒฐํ•ฉ"์ด ์™œ ๋‚˜์œ๊ฐ€? (ํžŒํŠธ: 5์ฃผ์ฐจ ๊ด€์‹ฌ์‚ฌ ๋ถ„๋ฆฌ)
  • ํ”„๋กœ๊ทธ๋ž˜๋ฐ ๋ฐฉ์‹์ด ํ•„์š”ํ•œ ์ผ€์ด์Šค๋Š”? (ํžŒํŠธ: ๋™์  ํŠธ๋žœ์žญ์…˜ ๋ฒ”์œ„ ๊ฒฐ์ •)

Unit 3.2 โ€” ํ”„๋ก์‹œ ๋„์ž… ์ „: ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง ์•ˆ์˜ ํŠธ๋žœ์žญ์…˜ ์ฝ”๋“œ

์„ ์ˆ˜ ์ง€์‹: Unit 3.1

ํ”„๋ก์‹œ ๋„์ž… ์ „ ์ฝ”๋“œ:

public class Service {
    public void logic() {
        // โ‘  ํŠธ๋žœ์žญ์…˜ ์‹œ์ž‘
        TransactionStatus status = transactionManager.getTransaction(
            new DefaultTransactionDefinition()
        );
        
        try {
            // โ‘ก ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง
            bizLogic(fromId, toId, money);
            
            // โ‘ข ์„ฑ๊ณต ์‹œ ์ปค๋ฐ‹
            transactionManager.commit(status);
        } catch (Exception e) {
            // โ‘ฃ ์‹คํŒจ ์‹œ ๋กค๋ฐฑ
            transactionManager.rollback(status);
            throw new IllegalStateException(e);
        }
    }
}

๋ฌธ์ œ์ :

  • ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง(โ‘ก)๊ณผ ํŠธ๋žœ์žญ์…˜ ์ฝ”๋“œ(โ‘ โ‘ขโ‘ฃ)๊ฐ€ ํ•œ ๊ณณ์—
  • ์‹œ๊ฐ„ ์ธก์ •ยท๋กœ๊น…ยท์˜ˆ์™ธ ๋ณ€ํ™˜๊นŒ์ง€ ์ถ”๊ฐ€ํ•˜๋ฉด ๋ฐฐ๋ณด๋‹ค ๋ฐฐ๊ผฝ
  • ๋งค ๋ฉ”์„œ๋“œ๋งˆ๋‹ค ๋ฐ˜๋ณต

์ž๊ธฐ ์ ๊ฒ€

  • 8์ฃผ์ฐจ Phase 1์˜ ๋กœ๊ทธ ์ถ”์ ๊ธฐ ๋ฌธ์ œ์™€ ๊ฐ™์€๊ฐ€?
  • 5์ฃผ์ฐจ์˜ ์–ด๋–ค ๋””์ž์ธ ํŒจํ„ด์ด ์ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ–ˆ๋Š”๊ฐ€? (ํžŒํŠธ: ํ…œํ”Œ๋ฆฟ ๋ฉ”์†Œ๋“œ, ์ „๋žต)

Unit 3.3 โ€” ํ”„๋ก์‹œ ๋„์ž… ํ›„: ์ˆœ์ˆ˜ ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง๋งŒ

์„ ์ˆ˜ ์ง€์‹: Unit 3.2, 8-9์ฃผ์ฐจ Phase 6

ํ”„๋ก์‹œ ๋„์ž… ํ›„ โ€” ๋น„์ฆˆ๋‹ˆ์Šค ์ฝ”๋“œ:

public class Service {
    public void logic() {
        bizLogic(fromId, toId, money);  // ํŠธ๋žœ์žญ์…˜ ์ฝ”๋“œ 0
    }
}

ํ”„๋ก์‹œ๊ฐ€ ํ•˜๋Š” ์ผ (๊ฐœ๋…์  ์˜์‚ฌ์ฝ”๋“œ):

public class TransactionProxy {
    private MemberService target;
    
    public void logic() {
        TransactionStatus status = transactionManager.getTransaction(...);
        try {
            target.logic();  // ์‹ค์ œ ์„œ๋น„์Šค ํ˜ธ์ถœ
            transactionManager.commit(status);
        } catch (Exception e) {
            transactionManager.rollback(status);
            throw new IllegalStateException(e);
        }
    }
}

ํ•ต์‹ฌ ํ†ต์ฐฐ:

"ํŠธ๋žœ์žญ์…˜ ํ”„๋ก์‹œ๊ฐ€ ํŠธ๋žœ์žญ์…˜ ์ฒ˜๋ฆฌ ๋กœ์ง์„ ๋ชจ๋‘ ๊ฐ€์ ธ๊ฐ„๋‹ค.
์„œ๋น„์Šค ๊ณ„์ธต์—๋Š” ์ˆœ์ˆ˜ํ•œ ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง๋งŒ ๋‚จ๋Š”๋‹ค."

์ž๊ธฐ ์ ๊ฒ€

  • ์ด ๊ตฌ์กฐ๊ฐ€ ๊ฐ€๋Šฅํ•œ ์ด์œ ๋Š” 8-9์ฃผ์ฐจ ์–ด๋–ค ๋ฉ”์ปค๋‹ˆ์ฆ˜ ๋•์ธ๊ฐ€? (ํžŒํŠธ: ๋นˆ ํ›„์ฒ˜๋ฆฌ๊ธฐ, AnnotationAwareAspectJAutoProxyCreator)
  • ํ”„๋ก์‹œ๊ฐ€ ๊ฐ€์ ธ๊ฐ„ ์ฑ…์ž„ 4๊ฐ€์ง€๋ฅผ ๋‹ค์‹œ ๋‚˜์—ดํ•˜๋ฉด?

๐Ÿ“š Phase 4 โ€” ๋นˆ ๋ผ์ดํ”„์‚ฌ์ดํด์˜ ํ•จ์ • (โ˜… @PostConstruct + @Transactional)

๋ชฉํ‘œ: 9์ฃผ์ฐจ์˜ internal call ํ•จ์ •๊ณผ ์ง์„ ์ด๋ฃจ๋Š” ๋˜ ํ•˜๋‚˜์˜ ๋ฉด์ ‘ ๋‹จ๊ณจ ํ•จ์ •์„ ๋งˆ์Šคํ„ฐํ•œ๋‹ค.

Unit 4.1 โ€” @PostConstruct์˜ ์—ญํ• ๊ณผ ์ ํ•ฉ ์‚ฌ์šฉ์ฒ˜

์„ ์ˆ˜ ์ง€์‹: 5์ฃผ์ฐจ Phase 8 (๋นˆ ์ƒ๋ช…์ฃผ๊ธฐ)

ํ•ต์‹ฌ ๊ฐœ๋…

@PostConstruct:

  • "๊ฐ์ฒด ์ƒ์„ฑ + ์˜์กด์„ฑ ์ฃผ์ž… ์™„๋ฃŒ ์งํ›„" ์‹คํ–‰
  • ์ดˆ๊ธฐํ™” ์ฝ”๋“œ๋ฅผ ๋‘๋Š” ํ‘œ์ค€ ์–ด๋…ธํ…Œ์ด์…˜

์ „ํ˜•์  ์‚ฌ์šฉ์ฒ˜:

  • ์บ์‹œ ์ดˆ๊ธฐ ๋กœ๋”ฉ
  • ์™ธ๋ถ€ ์‹œ์Šคํ…œ ์—ฐ๊ฒฐ ๊ฒ€์ฆ
  • ์ •์  ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ ๋กœ๋”ฉ
@Component
public class CacheInitializer {
    private final CacheService cacheService;
    
    public CacheInitializer(CacheService cacheService) {
        this.cacheService = cacheService;
    }
    
    @PostConstruct
    public void loadCache() {
        cacheService.initializeCache();  // ์•ฑ ์‹œ์ž‘ ์‹œ ํ•œ ๋ฒˆ๋งŒ
    }
}

์œ ์‚ฌ ๋„๊ตฌ ๋น„๊ต:

  • @PostConstruct: ํ‘œ์ค€ (JSR-250), ๋‹จ์ผ ๋นˆ ์ƒ๋ช…์ฃผ๊ธฐ
  • InitializingBean.afterPropertiesSet(): Spring ์ธํ„ฐํŽ˜์ด์Šค
  • ์ƒ์„ฑ์ž ์ง์ ‘ ์ž‘์—…: DI ์™„๋ฃŒ ์ „์ด๋ผ ์˜์กด์„ฑ ์‚ฌ์šฉ ๋ถˆ๊ฐ€

์ž๊ธฐ ์ ๊ฒ€

  • ์ƒ์„ฑ์ž์—์„œ ์ดˆ๊ธฐํ™” ์ž‘์—…์„ ํ•˜๋ฉด ์–ด๋–ค ๋ฌธ์ œ๊ฐ€? (ํžŒํŠธ: ์˜์กด์„ฑ ๋ฏธ์™„)
  • @PostConstruct๊ฐ€ 5์ฃผ์ฐจ์˜ ์–ด๋–ค ๋ผ์ดํ”„์‚ฌ์ดํด ๋‹จ๊ณ„์—์„œ ํ˜ธ์ถœ๋˜๋Š”๊ฐ€?

Unit 4.2 โ€” @PostConstruct + @Transactional์˜ ํ•จ์ • (โ˜…โ˜…โ˜… ๋ฉด์ ‘ ๋‹จ๊ณจ)

์„ ์ˆ˜ ์ง€์‹: Unit 4.1, 9์ฃผ์ฐจ Phase 7~10

ํ•ต์‹ฌ ํ•จ์ •

@Component
public class DataInitializer {

    @PostConstruct
    @Transactional         // โš ๏ธ ํŠธ๋žœ์žญ์…˜ ์ ์šฉ ์•ˆ ๋จ!
    public void initV1() {
        log.info("Hello init @PostConstruct");
        // DB ์ž‘์—… ์‹œ๋„... ํŠธ๋žœ์žญ์…˜ ์—†์ด ์‹คํ–‰๋จ
    }
}

์™œ ์•ˆ ๋˜๋Š”๊ฐ€:
1. ๋นˆ์ด ์ƒ์„ฑ๋˜๊ณ  ์˜์กด์„ฑ ์ฃผ์ž… ์™„๋ฃŒ
2. @PostConstruct๊ฐ€ ๋จผ์ € ์‹คํ–‰ โ† ์ด ์‹œ์ !
3. ๊ทธ ํ›„์— ํŠธ๋žœ์žญ์…˜ AOP๊ฐ€ ์ ์šฉ (๋นˆ ํ›„์ฒ˜๋ฆฌ๊ธฐ)
4. โ†’ @PostConstruct ํ˜ธ์ถœ ์‹œ์ ์—๋Š” ํ”„๋ก์‹œ๊ฐ€ ์•„์ง ๋ฏธ์กด์žฌ
5. โ†’ @Transactional์ด ๋ฌด์‹œ๋จ

์ค‘์š” โ€” 9์ฃผ์ฐจ Phase 7๊ณผ์˜ ์—ฐ๊ฒฐ:

  • ์ž๋™ ํ”„๋ก์‹œ ์ƒ์„ฑ๊ธฐ(AnnotationAwareAspectJAutoProxyCreator)๊ฐ€ ๋นˆ ํ›„์ฒ˜๋ฆฌ๊ธฐ๋กœ ๋™์ž‘
  • @PostConstruct ํ˜ธ์ถœ์€ ๋นˆ ํ›„์ฒ˜๋ฆฌ๊ธฐ ์ ์šฉ ์ด์ „

internal call ํ•จ์ •๊ณผ์˜ ๋น„๊ต:

ํ•จ์ •9์ฃผ์ฐจ Internal Call10์ฃผ์ฐจ @PostConstruct
๋ณธ์งˆํ”„๋ก์‹œ๋ฅผ ๊ฑฐ์น˜์ง€ ์•Š๋Š” ํ˜ธ์ถœํ”„๋ก์‹œ๊ฐ€ ์•„์ง ๋งŒ๋“ค์–ด์ง€์ง€ ์•Š์Œ
์‹œ์ ๋Ÿฐํƒ€์ž„ (๊ฐ์ฒด ์ž์ฒด ํ˜ธ์ถœ)์ดˆ๊ธฐํ™” ์‹œ์ 
ํ•ด๊ฒฐํด๋ž˜์Šค ๋ถ„๋ฆฌApplicationReadyEvent

์ž๊ธฐ ์ ๊ฒ€

  • ์ด ํ•จ์ •์„ ๋ชจ๋ฅด๊ณ  ์บ์‹œ ์ดˆ๊ธฐํ™”์— ํŠธ๋žœ์žญ์…˜์„ ๊ฑธ๋ฉด ์–ด๋–ค ์‚ฌ๊ณ ๊ฐ€?
  • "ํ”„๋ก์‹œ๊ฐ€ ์—†๋‹ค"๋Š” ๋ง์˜ ์ •ํ™•ํ•œ ์˜๋ฏธ๋Š”?

Unit 4.3 โ€” ํ•ด๊ฒฐ์ฑ…: ApplicationReadyEvent

์„ ์ˆ˜ ์ง€์‹: Unit 4.2

ํ•ต์‹ฌ ํ•ด๊ฒฐ

@Component
public class DataInitializer {

    @EventListener(value = ApplicationReadyEvent.class)
    @Transactional         // โœ… ์ •์ƒ ๋™์ž‘
    public void init2() {
        log.info("Hello init ApplicationReadyEvent");
        // DB ์ž‘์—…์ด ํŠธ๋žœ์žญ์…˜ ์•ˆ์—์„œ ์‹คํ–‰๋จ
    }
}

์™œ ๋˜๋Š”๊ฐ€:

  • ApplicationReadyEvent = ์ปจํ…Œ์ด๋„ˆ๊ฐ€ ์™„์ „ํžˆ ์ƒ์„ฑ๋œ ํ›„ ๋ฐœํ–‰๋˜๋Š” ์ด๋ฒคํŠธ
  • ์ด ์‹œ์ ์—๋Š” ๋ชจ๋“  ๋นˆ์ด ํ”„๋ก์‹œ๋กœ ๊ต์ฒด ์™„๋ฃŒ
  • โ†’ @Transactional ์ •์ƒ ์ ์šฉ

์Šคํ”„๋ง ๋ถ€ํŠธ์˜ ๋ผ์ดํ”„์‚ฌ์ดํด ์ด๋ฒคํŠธ 4์ข…:

  • ApplicationStartingEvent โ€” ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์‹œ์ž‘
  • ApplicationEnvironmentPreparedEvent โ€” ํ™˜๊ฒฝ ์ •๋ณด ์ค€๋น„
  • ApplicationContextInitializedEvent โ€” ์ปจํ…์ŠคํŠธ ์ดˆ๊ธฐํ™”
  • ApplicationReadyEvent โ€” ๋ชจ๋“  ์ค€๋น„ ์™„๋ฃŒ (์‚ฌ์šฉ ๊ถŒ์žฅ)

๋‹ค๋ฅธ ๋Œ€์•ˆ:

  • CommandLineRunner / ApplicationRunner ์ธํ„ฐํŽ˜์ด์Šค
  • ๋ณ„๋„์˜ ํŠธ๋žœ์žญ์…˜ ๋นˆ์œผ๋กœ ๋ถ„๋ฆฌ + ๋ช…์‹œ์  ํ˜ธ์ถœ
  • TransactionTemplate (ํ”„๋กœ๊ทธ๋ž˜๋ฐ ๋ฐฉ์‹)

์ž๊ธฐ ์ ๊ฒ€

  • ApplicationReadyEvent์™€ @PostConstruct๊ฐ€ ํ˜ธ์ถœ๋˜๋Š” ์ˆœ์„œ๋Š”?
  • ILIC ์‹œ์ž‘ ์‹œ ๋งˆ์Šคํ„ฐ ๋ฐ์ดํ„ฐ๋ฅผ DB์—์„œ ๋ฉ”๋ชจ๋ฆฌ๋กœ ๋กœ๋“œํ•˜๋Š” ์ž‘์—…์—๋Š” ์–ด๋А ๊ฒƒ์ด ์ ํ•ฉํ•œ๊ฐ€?

๐Ÿ“š Phase 5 โ€” ํŠธ๋žœ์žญ์…˜ ๊ฒฉ๋ฆฌ ์ˆ˜์ค€ (โ˜… DB์™€ Spring์˜ ๊ฒฝ๊ณ„)

๋ชฉํ‘œ: 6์ฃผ์ฐจ ACID์˜ 'I(Isolation)'๋ฅผ ๊นŠ์ด ํŒŒํ—ค์นœ๋‹ค. 3๊ฐ€์ง€ ์ถฉ๋Œ โ†’ 4๊ฐ€์ง€ ๊ฒฉ๋ฆฌ ์ˆ˜์ค€ ๋งคํŠธ๋ฆญ์Šค๋ฅผ ์™„์„ฑํ•œ๋‹ค.

Unit 5.1 โ€” ๊ฒฉ๋ฆฌ ์ˆ˜์ค€์ด๋ž€

์„ ์ˆ˜ ์ง€์‹: 6์ฃผ์ฐจ Phase 6 (ACID)

ํ•ต์‹ฌ ๊ฐœ๋…

๊ฒฉ๋ฆฌ ์ˆ˜์ค€ (Isolation Level):

"ํŠธ๋žœ์žญ์…˜๋ผ๋ฆฌ ์–ผ๋งˆ๋‚˜ ์„œ๋กœ ๊ณ ๋ฆฝ ๋˜์–ด ์žˆ๋Š”์ง€์˜ ์ˆ˜์ค€"

์™œ ํ•„์š”ํ•œ๊ฐ€:

  • ํŠธ๋žœ์žญ์…˜์˜ I (Isolation) ๋ณด์žฅ ์ˆ˜๋‹จ
  • Locking์œผ๋กœ ํ•ด๊ฒฐ ๊ฐ€๋Šฅํ•˜์ง€๋งŒ ๋ฌด์กฐ๊ฑด ๊ฐ•ํ•œ ๋ฝ = ์„ฑ๋Šฅ ์ €ํ•˜
  • ์ ์ ˆํ•œ ์ˆ˜์ค€ = ์ •ํ•ฉ์„ฑ๊ณผ ์„ฑ๋Šฅ์˜ ๊ท ํ˜•์ 

ํŠธ๋ ˆ์ด๋“œ์˜คํ”„:

  • ๊ฒฉ๋ฆฌ ์ˆ˜์ค€ โ†‘ โ†’ ์ •ํ•ฉ์„ฑ โ†‘, ๋™์‹œ์„ฑ โ†“
  • ๊ฒฉ๋ฆฌ ์ˆ˜์ค€ โ†“ โ†’ ์ •ํ•ฉ์„ฑ โ†“, ๋™์‹œ์„ฑ โ†‘

์ž๊ธฐ ์ ๊ฒ€

  • 6์ฃผ์ฐจ ACID์˜ I์™€ ๊ฒฉ๋ฆฌ ์ˆ˜์ค€์˜ ๊ด€๊ณ„๋Š”?
  • ๊ฒฉ๋ฆฌ ์ˆ˜์ค€์ด ๋™์‹œ์„ฑ๊ณผ ํŠธ๋ ˆ์ด๋“œ์˜คํ”„ ๊ด€๊ณ„์ธ ์ด์œ ๋Š”?

Unit 5.2 โ€” Dirty Read (์ปค๋ฐ‹ ์•ˆ ๋œ ๋ฐ์ดํ„ฐ ์ฝ๊ธฐ)

์„ ์ˆ˜ ์ง€์‹: Unit 5.1

ํ•ต์‹ฌ ์‹œ๋‚˜๋ฆฌ์˜ค

"์ปค๋ฐ‹๋˜์ง€ ์•Š์€ ๋‹ค๋ฅธ ํŠธ๋žœ์žญ์…˜์˜ ๋ฐ์ดํ„ฐ๋ฅผ ์ฝ์Œ"

์˜ˆ์‹œ:
1. ํŠธ๋žœ์žญ์…˜ A: x = 10 โ†’ 100 ๋ณ€๊ฒฝ (์ปค๋ฐ‹ X)
2. ํŠธ๋žœ์žญ์…˜ B: x = 100 ์กฐํšŒ โ† ์ž˜๋ชป๋œ ๊ฐ’
3. ํŠธ๋žœ์žญ์…˜ A: ๋กค๋ฐฑ
4. โ†’ B๋Š” ์กด์žฌํ•˜์ง€ ์•Š์€ ๊ฐ’์„ ๋ดค์Œ

ASCII ๋‹ค์ด์–ด๊ทธ๋žจ:

Time   T1                    T2
โ”€โ”€โ”€โ”€โ”€  โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€    โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
t1     UPDATE x=100
t2                            SELECT x โ†’ 100  โ† Dirty Read!
t3     ROLLBACK
                              (T2๋Š” ํ™˜์ƒ์˜ ๊ฐ’์„ ๋ณธ ๊ฒƒ)

์ž๊ธฐ ์ ๊ฒ€

  • B๊ฐ€ ๋ณธ ๊ฐ’์œผ๋กœ ๋˜ ๋‹ค๋ฅธ ์ž‘์—…์„ ํ–ˆ๋‹ค๋ฉด ์–ด๋–ค ์‚ฌ๊ณ ๊ฐ€?
  • ๊ฐ€์žฅ ์œ„ํ—˜ํ•œ read ๋ฌธ์ œ 3๊ฐ€์ง€ ์ค‘ ์–ด๋–ค ๊ฒƒ?

Unit 5.3 โ€” Non-repeatable Read (๋ฐ˜๋ณต ์ฝ๊ธฐ ๋ถˆ๊ฐ€)

์„ ์ˆ˜ ์ง€์‹: Unit 5.2

ํ•ต์‹ฌ ์‹œ๋‚˜๋ฆฌ์˜ค

"๊ฐ™์€ ํŠธ๋žœ์žญ์…˜ ์•ˆ์—์„œ ๊ฐ™์€ ๋ฐ์ดํ„ฐ๋ฅผ ๋‘ ๋ฒˆ ์ฝ์—ˆ๋Š”๋ฐ ๊ฐ’์ด ๋‹ค๋ฆ„"

์›์ธ: ๋‹ค๋ฅธ ํŠธ๋žœ์žญ์…˜์ด ์ˆ˜์ •/์‚ญ์ œ

์˜ˆ์‹œ:
1. ํŠธ๋žœ์žญ์…˜ A: x ์กฐํšŒ โ†’ 10
2. ํŠธ๋žœ์žญ์…˜ B: x = 10 โ†’ 50 ๋ณ€๊ฒฝ ํ›„ ์ปค๋ฐ‹
3. ํŠธ๋žœ์žญ์…˜ A: x ๋‹ค์‹œ ์กฐํšŒ โ†’ 50 โ† ๊ฐ™์€ ํŠธ๋žœ์žญ์…˜์ธ๋ฐ ๋‹ค๋ฆ„!

์–ธ์ œ ๋ฌธ์ œ์ธ๊ฐ€:

  • ๊ฐ™์€ ํŠธ๋žœ์žญ์…˜ ์•ˆ์—์„œ ์ผ๊ด€๋œ ์Šค๋ƒ…์ƒท์ด ํ•„์š”ํ•œ ๊ฒฝ์šฐ
  • ์˜ˆ: ๋ณด๊ณ ์„œ ์ƒ์„ฑ ์ค‘ ๋ฐ์ดํ„ฐ๊ฐ€ ๋ฐ”๋€Œ๋ฉด ํ•ฉ๊ณ„๊ฐ€ ํ‹€์–ด์ง

์ž๊ธฐ ์ ๊ฒ€

  • Dirty Read์™€ Non-repeatable Read์˜ ๊ฒฐ์ •์  ์ฐจ์ด๋Š”? (ํžŒํŠธ: ์ปค๋ฐ‹ ์—ฌ๋ถ€)
  • 6์ฃผ์ฐจ ๊ฒฉ๋ฆฌ์„ฑ์˜ ์ •์˜๋ฅผ ๋‹ค์‹œ ๋ณธ๋‹ค๋ฉด ์ด ๋ฌธ์ œ์™€์˜ ๊ด€๊ณ„๋Š”?

Unit 5.4 โ€” Phantom Read (์œ ๋ น ํ–‰)

์„ ์ˆ˜ ์ง€์‹: Unit 5.3

ํ•ต์‹ฌ ์‹œ๋‚˜๋ฆฌ์˜ค

"๊ฐ™์€ ์กฐ๊ฑด์œผ๋กœ ๋‘ ๋ฒˆ ์กฐํšŒํ–ˆ๋Š”๋ฐ ๊ฒฐ๊ณผ ํ–‰ ์ˆ˜๊ฐ€ ๋‹ค๋ฆ„"

์›์ธ: ๋‹ค๋ฅธ ํŠธ๋žœ์žญ์…˜์ด ์‚ฝ์ž…(๋˜๋Š” ์‚ญ์ œ)

์˜ˆ์‹œ:
1. ํŠธ๋žœ์žญ์…˜ A: ์ž”์•ก โ‰ฅ 100๋งŒ ์กฐ๊ฑด์œผ๋กœ ์กฐํšŒ โ†’ 5๊ฑด
2. ํŠธ๋žœ์žญ์…˜ B: ์ž”์•ก 200๋งŒ ์‹ ๊ทœ ๊ณ„์ขŒ INSERT ํ›„ ์ปค๋ฐ‹
3. ํŠธ๋žœ์žญ์…˜ A: ๊ฐ™์€ ์กฐ๊ฑด ๋‹ค์‹œ ์กฐํšŒ โ†’ 6๊ฑด โ† "์œ ๋ น" ํ–‰ ๋“ฑ์žฅ

Non-repeatable Read์™€์˜ ์ฐจ์ด:

  • Non-repeatable Read: ๊ธฐ์กด ํ–‰์˜ ๊ฐ’ ๋ณ€๊ฒฝ
  • Phantom Read: ์ƒˆ๋กœ์šด ํ–‰ ๋“ฑ์žฅ (๋˜๋Š” ์‚ฌ๋ผ์ง)

์ž๊ธฐ ์ ๊ฒ€

  • ํ–‰ ์ˆ˜๊ฐ€ ๊ฐ™์„ ์ˆ˜ ์žˆ์–ด๋„ phantom read์ธ ๊ฒฝ์šฐ๋Š”? (ํžŒํŠธ: ์‚ญ์ œ + ์‚ฝ์ž…)
  • ILIC์˜ "์šด์ž„ ๊ฒฌ์  ๋ชฉ๋ก" ์กฐํšŒ ์ค‘ phantom read๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด?

Unit 5.5 โ€” 4๊ฐ€์ง€ ๊ฒฉ๋ฆฌ ์ˆ˜์ค€๊ณผ ๋งคํŠธ๋ฆญ์Šค (โ˜… ๋ฉด์ ‘ ๋‹จ๊ณจ)

์„ ์ˆ˜ ์ง€์‹: Unit 5.2~5.4

ํ•ต์‹ฌ ๋งคํŠธ๋ฆญ์Šค:

๊ฒฉ๋ฆฌ ์ˆ˜์ค€Dirty ReadNon-repeatable ReadPhantom Read๊ธฐ๋ณธ ์ฑ„ํƒ DB
READ UNCOMMITTED (0)โŒโŒโŒ(ํ‘œ์ค€ ์ธ์ • X)
READ COMMITTED (1)โœ…โŒโŒOracle, PostgreSQL
REPEATABLE READ (2)โœ…โœ…โŒMySQL โญ
SERIALIZABLE (3)โœ…โœ…โœ…(์„ฑ๋Šฅ ์ตœ์ €)

โœ… = ๋ฐฉ์–ด๋จ, โŒ = ๋ฐœ์ƒ ๊ฐ€๋Šฅ

๊ฐ ์ˆ˜์ค€ ์ •๋ฆฌ:

Level 0 โ€” READ UNCOMMITTED:

  • ์ปค๋ฐ‹ ๋ฌด๊ด€ ์กฐํšŒ
  • ์ •ํ•ฉ์„ฑ ๋ฌธ์ œ ๅคš โ†’ ํ‘œ์ค€์—์„œ ์ธ์ • ์•ˆ ํ•จ
  • ๊ฑฐ์˜ ์‚ฌ์šฉ ์•ˆ ํ•จ

Level 1 โ€” READ COMMITTED:

  • ์ปค๋ฐ‹๋œ ๋ฐ์ดํ„ฐ๋งŒ ์กฐํšŒ
  • Oracle, PostgreSQL ๊ธฐ๋ณธ
  • Dirty Read๋งŒ ๋ฐฉ์ง€

Level 2 โ€” REPEATABLE READ โญ:

  • ํŠธ๋žœ์žญ์…˜ ์‹œ์ž‘ ์‹œ์ ์˜ ์Šค๋ƒ…์ƒท ์œ ์ง€
  • MySQL InnoDB ๊ธฐ๋ณธ
  • Phantom Read๋งŒ ๊ฐ€๋Šฅ (MySQL์€ Gap Lock์œผ๋กœ ์ผ๋ถ€ ๋ฐฉ์ง€)

Level 3 โ€” SERIALIZABLE:

  • ๋ชจ๋“  ์ถฉ๋Œ ๋ฐฉ์ง€
  • ๋™์‹œ์„ฑ ์ตœ์ € โ†’ ๊ฑฐ์˜ ์‚ฌ์šฉ ์•ˆ ํ•จ
  • ๋งค์šฐ ์—„๊ฒฉํ•œ ์ •ํ•ฉ์„ฑ์ด ํ•„์š”ํ•œ ์˜์—ญ์—์„œ๋งŒ

Spring์—์„œ ๊ฒฉ๋ฆฌ ์ˆ˜์ค€ ์ง€์ •:

@Transactional(isolation = Isolation.REPEATABLE_READ)
public void method() { ... }

์ž๊ธฐ ์ ๊ฒ€

  • ILIC๊ฐ€ ์‚ฌ์šฉํ•˜๋Š” MySQL์˜ ๊ธฐ๋ณธ ๊ฒฉ๋ฆฌ ์ˆ˜์ค€์€?
  • "์„ฑ๋Šฅ์„ ์œ„ํ•ด ๊ฒฉ๋ฆฌ ์ˆ˜์ค€์„ ๋‚ฎ์ถ”๊ฒ ๋‹ค"๋Š” ๊ฒฐ์ • ์‹œ ๊ฒ€ํ† ํ•  4๊ฐ€์ง€๋Š”?
  • SERIALIZABLE์ด ๊ฑฐ์˜ ์•ˆ ์“ฐ์ด๋Š” ์ด์œ ๋Š”?

๐ŸŽ“ ์ข…ํ•ฉ ์ž๊ธฐ ์ ๊ฒ€ (10์ฃผ์ฐจ ์กธ์—… ์‹œํ—˜)

@Import

  1. @Import์˜ ์ •์˜์™€ ์‚ฌ์šฉ ์‹œ์ ์€?
  2. @Import์™€ @ComponentScan์˜ ์ฐจ์ด๋Š”?
  3. ์™ธ๋ถ€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์˜ @Configuration์„ ๋“ฑ๋กํ•  ๋•Œ ์–ด๋А ๊ฒƒ์„ ์“ฐ๋Š”๊ฐ€?

ํŠธ๋žœ์žญ์…˜ ์ถ”์ƒํ™”

  1. PlatformTransactionManager ์ธํ„ฐํŽ˜์ด์Šค์˜ 3๊ฐ€์ง€ ํ•ต์‹ฌ ๋ฉ”์„œ๋“œ๋Š”?
  2. Spring Boot๊ฐ€ ์ž๋™์œผ๋กœ ์–ด๋–ค TransactionManager๋ฅผ ๋“ฑ๋กํ•˜๋Š”์ง€ ์„ค๋ช…ํ•˜๋ผ
  3. 7์ฃผ์ฐจ DataSource ์ถ”์ƒํ™”์™€ ๊ฐ™์€ ์‚ฌ์ƒ์ธ ์ด์œ ๋Š”?

์„ ์–ธ์  vs ํ”„๋กœ๊ทธ๋ž˜๋ฐ ๋ฐฉ์‹

  1. ๋‘ ๋ฐฉ์‹์˜ ์ฐจ์ด๋ฅผ ํ•œ ๋ฌธ์žฅ์”ฉ์œผ๋กœ?
  2. "ํ”„๋กœ๊ทธ๋ž˜๋ฐ ๋ฐฉ์‹์ด ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง๊ณผ ๊ฐ•ํ•˜๊ฒŒ ๊ฒฐํ•ฉ"์˜ ์˜๋ฏธ๋Š”?
  3. ํ”„๋ก์‹œ ๋„์ž… ์ „ํ›„ ์„œ๋น„์Šค ์ฝ”๋“œ์˜ ์ฐจ์ด๋ฅผ ์„ค๋ช…ํ•˜๋ผ

@PostConstruct ํ•จ์ • (โ˜…)

  1. @PostConstruct + @Transactional์ด ๋™์ž‘ํ•˜์ง€ ์•Š๋Š” ์ด์œ ๋Š”?
  2. 9์ฃผ์ฐจ internal call ํ•จ์ •๊ณผ์˜ ๋ณธ์งˆ์  ์ฐจ์ด๋Š”?
  3. ApplicationReadyEvent๊ฐ€ ํ•ด๊ฒฐ์ฑ…์ธ ์ด์œ ๋Š”?
  4. ์บ์‹œ ์ดˆ๊ธฐํ™” + ํŠธ๋žœ์žญ์…˜์ด ํ•„์š”ํ•œ ์‹œ๋‚˜๋ฆฌ์˜ค์— ์–ด๋–ค ๋„๊ตฌ๋ฅผ ์“ธ ๊ฒƒ์ธ๊ฐ€?

ํŠธ๋žœ์žญ์…˜ ๊ฒฉ๋ฆฌ ์ˆ˜์ค€ (โ˜…)

  1. ๊ฒฉ๋ฆฌ ์ˆ˜์ค€์ด ๋™์‹œ์„ฑ๊ณผ ํŠธ๋ ˆ์ด๋“œ์˜คํ”„ ๊ด€๊ณ„์ธ ์ด์œ ๋Š”?
  2. Dirty Read, Non-repeatable Read, Phantom Read์˜ ์ฐจ์ด๋ฅผ ์‹œ๋‚˜๋ฆฌ์˜ค๋กœ ์„ค๋ช…ํ•˜๋ผ
  3. Non-repeatable Read์™€ Phantom Read์˜ ๊ฒฐ์ •์  ์ฐจ์ด๋Š”?
  4. 4๊ฐ€์ง€ ๊ฒฉ๋ฆฌ ์ˆ˜์ค€ ร— 3๊ฐ€์ง€ ์ถฉ๋Œ ๋งคํŠธ๋ฆญ์Šค๋ฅผ ์ž‘์„ฑํ•˜๋ผ
  5. MySQL์˜ ๊ธฐ๋ณธ ๊ฒฉ๋ฆฌ ์ˆ˜์ค€๊ณผ ๊ทธ ์ด์œ ๋Š”?
  6. Oracle/PostgreSQL์˜ ๊ธฐ๋ณธ ๊ฒฉ๋ฆฌ ์ˆ˜์ค€๊ณผ ๊ทธ ์ด์œ ๋Š”?
  7. ILIC์—์„œ ๊ฒฉ๋ฆฌ ์ˆ˜์ค€์„ ๋ช…์‹œ์ ์œผ๋กœ ๋ณ€๊ฒฝํ•˜๊ณ  ์‹ถ์€ ์‹œ๋‚˜๋ฆฌ์˜ค๋Š”?

๐Ÿ“Œ ํ•™์Šต ์šด์˜ ํŒ

9-์„น์…˜ ๋งˆ์Šคํ„ฐ ํ”„๋กฌํ”„ํŠธ๋กœ ๊นŠ์ด ํŒŒ์•ผ ํ•  Unit

โ˜…โ˜…โ˜… ๋ฉด์ ‘ ๋‹จ๊ณจ (๋ฐ˜๋“œ์‹œ):

  • Unit 4.2 โ€” @PostConstruct + @Transactional ํ•จ์ • (9์ฃผ์ฐจ internal call๊ณผ ์ง)
  • Unit 5.5 โ€” 4๊ฐ€์ง€ ๊ฒฉ๋ฆฌ ์ˆ˜์ค€ ร— 3๊ฐ€์ง€ ์ถฉ๋Œ ๋งคํŠธ๋ฆญ์Šค

โ˜…โ˜… ๋งค์šฐ ๊ถŒ์žฅ:

  • Unit 4.3 โ€” ApplicationReadyEvent ํŒจํ„ด
  • Unit 5.2~5.4 โ€” 3๊ฐ€์ง€ read ๋ฌธ์ œ์˜ ์‹œ๋‚˜๋ฆฌ์˜ค

Phase๋ณ„ ์ง„๋„ ์ฒดํฌ๋ฆฌ์ŠคํŠธ

[ ] Phase 1 โ€” @Import (Unit 1.1~1.2)
[ ] Phase 2 โ€” ํŠธ๋žœ์žญ์…˜ ์ถ”์ƒํ™” ์ •๋ฆฌ (Unit 2.1~2.3)
[ ] Phase 3 โ€” ์„ ์–ธ์  vs ํ”„๋กœ๊ทธ๋ž˜๋ฐ ๋ฐฉ์‹ (Unit 3.1~3.3)
[ ] Phase 4 โ€” @PostConstruct ํ•จ์ • (Unit 4.1~4.3)  โ˜…
[ ] Phase 5 โ€” ํŠธ๋žœ์žญ์…˜ ๊ฒฉ๋ฆฌ ์ˆ˜์ค€ (Unit 5.1~5.5)  โ˜…
[ ] ์ข…ํ•ฉ ์ž๊ธฐ ์ ๊ฒ€ 20๋ฌธํ•ญ ํ†ต๊ณผ

๋‘ ํ•จ์ •์˜ ์ง โ€” 9์ฃผ์ฐจ์™€ 10์ฃผ์ฐจ

internal call ํ•จ์ •๊ณผ @PostConstruct ํ•จ์ •์€ ๊ฐ™์€ ๋ณธ์งˆ์˜ ๋‘ ์–ผ๊ตด:

9์ฃผ์ฐจ internal call10์ฃผ์ฐจ @PostConstruct
๋ณธ์งˆํ”„๋ก์‹œ๋ฅผ ๊ฑฐ์น˜์ง€ ์•Š๋Š” ํ˜ธ์ถœํ”„๋ก์‹œ๊ฐ€ ์•„์ง ๋งŒ๋“ค์–ด์ง€์ง€ ์•Š์Œ
์‹œ์ ๋Ÿฐํƒ€์ž„, this ํ˜ธ์ถœ ์‹œ๋นˆ ์ดˆ๊ธฐํ™” ์‹œ์ 
์ฆ์ƒ@Transactional ๋ฌด์‹œ@Transactional ๋ฌด์‹œ
ํ•ด๊ฒฐํด๋ž˜์Šค ๋ถ„๋ฆฌApplicationReadyEvent

โ†’ ๋‘ ํ•จ์ •์€ ํ•จ๊ป˜ ๋ฌถ์–ด ์™ธ์›Œ์•ผ ํ•œ๋‹ค (๋ฉด์ ‘ ๋นˆ์ถœ).

์‹ค์Šต ๊ถŒ์žฅ

Phase 4 ์‹ค์Šต:

  • @PostConstruct์— @Transactional ์ถ”๊ฐ€ โ†’ ํŠธ๋žœ์žญ์…˜์ด ์ ์šฉ ์•ˆ ๋˜๋Š” ๊ฒƒ ํ™•์ธ
  • TransactionSynchronizationManager.isActualTransactionActive() ๋กœ ๊ฒ€์ฆ
  • ApplicationReadyEvent๋กœ ๋ณ€๊ฒฝ โ†’ ์ •์ƒ ๋™์ž‘ ํ™•์ธ

Phase 5 ์‹ค์Šต:

  • MySQL์— ๋‘ ๊ฐœ ์„ธ์…˜ ์—ด๊ธฐ
  • ๊ฐ ๊ฒฉ๋ฆฌ ์ˆ˜์ค€์—์„œ Dirty Read / Non-repeatable / Phantom ์žฌํ˜„
  • SET TRANSACTION ISOLATION LEVEL ๋ช…๋ น์œผ๋กœ ์ˆ˜์ค€ ๋ณ€๊ฒฝ

1~10์ฃผ์ฐจ ํ†ตํ•ฉ ํ๋ฆ„์˜ ๋งˆ๋ฌด๋ฆฌ

ํŠธ๋žœ์žญ์…˜ ํ•™์Šต์˜ 5๋‹จ๊ณ„ ์™„๊ฒฐ:

  • 6์ฃผ์ฐจ: ํŠธ๋žœ์žญ์…˜ ACID ๊ฐœ๋… + JdbcTemplate
  • 7์ฃผ์ฐจ: PlatformTransactionManager + @Transactional ์ž…๋ฌธ
  • 8-9์ฃผ์ฐจ: AOP ๋ฉ”์ปค๋‹ˆ์ฆ˜ + @Transactional ๋™์ž‘ ์›๋ฆฌ + ํŠธ๋žœ์žญ์…˜ ์ „ํŒŒ
  • 10์ฃผ์ฐจ: ํŠธ๋žœ์žญ์…˜ ์ •๋ฆฌ + ๋นˆ ๋ผ์ดํ”„์‚ฌ์ดํด ํ•จ์ • + ๊ฒฉ๋ฆฌ ์ˆ˜์ค€ (์ง€๊ธˆ)

โ†’ ์ด์ œ ํŠธ๋žœ์žญ์…˜์˜ ๋ชจ๋“  ๊ฒƒ์„ ์•ˆ๋‹ค. 11์ฃผ์ฐจ๋ถ€ํ„ฐ๋Š” ์ƒˆ ์˜์—ญ์œผ๋กœ ์ง„์ž…ํ•  ์‹œ์ .

profile
Software Developer

0๊ฐœ์˜ ๋Œ“๊ธ€