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์ฃผ์ฐจ | 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์ฃผ์ฐจ (์ง๊ธ) | ํธ๋์ญ์ ์ ๋ฆฌ + ๋น ๋ผ์ดํ์ฌ์ดํด ํจ์ + ๊ฒฉ๋ฆฌ ์์ค | ํธ๋์ญ์ ํ์ต์ ๋ง๋ฌด๋ฆฌ |
| Day | Phase | ํ์ต ๋ชฉํ |
|---|---|---|
| 1์ผ์ฐจ | Phase 1 + 2 | @Import + ์คํ๋ง ํธ๋์ญ์ ์ถ์ํ ์ ๋ฆฌ |
| 2์ผ์ฐจ | Phase 3 | ์ ์ธ์ vs ํ๋ก๊ทธ๋๋ฐ + ํ๋ก์ ์ ์ฉ |
| 3์ผ์ฐจ | Phase 4 | @PostConstruct + @Transactional ํจ์ (โ ) |
| 4์ผ์ฐจ | Phase 5 | ํธ๋์ญ์ ๊ฒฉ๋ฆฌ ์์ค (โ ) |
| 5์ผ์ฐจ | ์ข ํฉ ์๊ธฐ ์ ๊ฒ + ์ค์ต | ์ ์ฒด ์ ๋ฆฌ |
์ฌ์ ์ผ์ (7์ผ): Phase 4ยท5์ ๊ฐ +1์ผ. ๊ฒฉ๋ฆฌ ์์ค์ ์ง์ SQL์ ๋๋ฆฌ๋ฉฐ ์๊ฐ์ ์ผ๋ก ์ฒดํํ๋ ๊ฒ ํจ๊ณผ์ .
๋ชฉํ: ์ฌ๋ฌ ์ค์ ํ์ผ๋ก ๋ถ๋ฆฌ๋ ๋น์ ํ๋๋ก ๋ฌถ๋ ์์ Spring ๋๊ตฌ๋ฅผ ์ตํ๋ค.
์ ์ ์ง์: 5์ฃผ์ฐจ Phase 8 (ApplicationContext)
ํต์ฌ ๊ฐ๋
๋ฌธ์ :
@Import ์ ํด๊ฒฐ:
@Configuration ํด๋์ค๋ฅผ ํ ๊ณณ์์ ๊ฒฐํฉ@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 {}
์๊ธฐ ์ ๊ฒ
@Import(AspectV1.class) ๋ฅผ ๋ณธ ๋งฅ๋ฝ์?@Import ์ @ComponentScan ์ ์ฐจ์ด๋? (ํํธ: ๋ช
์์ vs ์๋)์ ์ ์ง์: Unit 1.1
ํต์ฌ ํจํด
ํ๊ฒฝ๋ณ ์ค์ ๋ถ๋ฆฌ:
@Configuration
@Import({DatabaseConfig.class, SecurityConfig.class, CacheConfig.class})
public class ApplicationConfig {}
ํ ์คํธ์ฉ ์ค์ ์ถ๊ฐ:
@SpringBootTest
@Import(TestConfig.class) // ํ
์คํธ ์ ์ฉ ๋น ์ถ๊ฐ
class IntegrationTest {}
์ธ์ @Component ๋์ @Import?:
์๊ธฐ ์ ๊ฒ
๋ชฉํ: 7์ฃผ์ฐจ์์ ๋ค๋ฃฌ PlatformTransactionManager์ ๋ณธ์ง์ ๋ค์ ์ง๊ณ Spring Boot์ ์๋ ๊ตฌ์ฑ๊น์ง ์ ๋ฆฌํ๋ค.
์ ์ ์ง์: 7์ฃผ์ฐจ Phase 5
ํต์ฌ ๋ฌธ์
๊ธฐ์ ๋ง๋ค ํธ๋์ญ์ ์ฝ๋๊ฐ ๋ค๋ฆ:
connection.setAutoCommit(false) + commit() / rollback()EntityTransaction.begin() + commit() / rollback()๊ฒฐ๊ณผ:
โ ์ถ์ํ ํ์ = 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, MyBatis | DataSourceTransactionManager (= JdbcTransactionManager) |
| Hibernate (์ง์ ์ฌ์ฉ) | HibernateTransactionManager |
| JPA | JpaTransactionManager |
์๊ธฐ ์ ๊ฒ
์ ์ ์ง์: Unit 2.2
ํต์ฌ ๊ฐ๋
Spring Boot์ ์๋ ๊ตฌ์ฑ:
| ์์กด์ฑ | ์๋ ๋ฑ๋ก |
|---|---|
spring-boot-starter-jdbc | DataSourceTransactionManager |
spring-boot-starter-data-jpa | JpaTransactionManager |
๊ฐ๋ฐ์๊ฐ ํ ์ผ:
@Transactional ์ฌ์ฉILIC ์ฌ๋ก:
์๊ธฐ ์ ๊ฒ
--debug ์ถ๋ ฅ)๋ชฉํ: 9์ฃผ์ฐจ์์ ๋ณธ @Transactional์ ๋ณธ์ง์ "ํ๋ก์ ๋์ ์ ํ ์ฝ๋ ๋น๊ต" ๋ก ๋ค์ ํ๋ฒ ๋ชป ๋ฐ๋๋ค.
์ ์ ์ง์: 7์ฃผ์ฐจ Phase 7, 9์ฃผ์ฐจ Phase 10
ํต์ฌ ๊ฐ๋
| ๋ฐฉ์ | ์ ์ | ์ฅ์ | ๋จ์ |
|---|---|---|---|
์ ์ธ์ (@Transactional) | ์ด๋ ธํ ์ด์ ํ ์ค ์ ์ธ | ๋งค์ฐ ๊ฐํธ | ํจ์ ๅค (internal call ๋ฑ) |
| ํ๋ก๊ทธ๋๋ฐ (TransactionTemplate) | ํธ๋์ญ์ ์ฝ๋ ์ง์ ์์ฑ | ์ธ๋ฐํ ์ ์ด | ๋น์ฆ๋์ค ๋ก์ง๊ณผ ๊ฒฐํฉ |
ํ๋ก๊ทธ๋๋ฐ ๋ฐฉ์์ ํ๊ณ:
"์ ํ๋ฆฌ์ผ์ด์ ์ฝ๋๊ฐ ํธ๋์ญ์ ์ด๋ผ๋ ๊ธฐ์ ์ฝ๋์ ๊ฐํ๊ฒ ๊ฒฐํฉ"
์ค๋ฌด ๊ฒฐ๋ก :
"์ ์ธ์ ํธ๋์ญ์ ์ด ๊ฑฐ์ ํ์ค โ ํ๋ก๊ทธ๋๋ฐ ๋ฐฉ์์ ํน์ ์ผ์ด์ค์๋ง"
์๊ธฐ ์ ๊ฒ
์ ์ ์ง์: 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);
}
}
}
๋ฌธ์ ์ :
์๊ธฐ ์ ๊ฒ
์ ์ ์ง์: 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);
}
}
}
ํต์ฌ ํต์ฐฐ:
"ํธ๋์ญ์ ํ๋ก์๊ฐ ํธ๋์ญ์ ์ฒ๋ฆฌ ๋ก์ง์ ๋ชจ๋ ๊ฐ์ ธ๊ฐ๋ค.
์๋น์ค ๊ณ์ธต์๋ ์์ํ ๋น์ฆ๋์ค ๋ก์ง๋ง ๋จ๋๋ค."
์๊ธฐ ์ ๊ฒ
๋ชฉํ: 9์ฃผ์ฐจ์ internal call ํจ์ ๊ณผ ์ง์ ์ด๋ฃจ๋ ๋ ํ๋์ ๋ฉด์ ๋จ๊ณจ ํจ์ ์ ๋ง์คํฐํ๋ค.
์ ์ ์ง์: 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 ์ธํฐํ์ด์ค์๊ธฐ ์ ๊ฒ
์ ์ ์ง์: 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)๊ฐ ๋น ํ์ฒ๋ฆฌ๊ธฐ๋ก ๋์internal call ํจ์ ๊ณผ์ ๋น๊ต:
| ํจ์ | 9์ฃผ์ฐจ Internal Call | 10์ฃผ์ฐจ @PostConstruct |
|---|---|---|
| ๋ณธ์ง | ํ๋ก์๋ฅผ ๊ฑฐ์น์ง ์๋ ํธ์ถ | ํ๋ก์๊ฐ ์์ง ๋ง๋ค์ด์ง์ง ์์ |
| ์์ | ๋ฐํ์ (๊ฐ์ฒด ์์ฒด ํธ์ถ) | ์ด๊ธฐํ ์์ |
| ํด๊ฒฐ | ํด๋์ค ๋ถ๋ฆฌ | ApplicationReadyEvent |
์๊ธฐ ์ ๊ฒ
์ ์ ์ง์: Unit 4.2
ํต์ฌ ํด๊ฒฐ
@Component
public class DataInitializer {
@EventListener(value = ApplicationReadyEvent.class)
@Transactional // โ
์ ์ ๋์
public void init2() {
log.info("Hello init ApplicationReadyEvent");
// DB ์์
์ด ํธ๋์ญ์
์์์ ์คํ๋จ
}
}
์ ๋๋๊ฐ:
ApplicationReadyEvent = ์ปจํ
์ด๋๊ฐ ์์ ํ ์์ฑ๋ ํ ๋ฐํ๋๋ ์ด๋ฒคํธ์คํ๋ง ๋ถํธ์ ๋ผ์ดํ์ฌ์ดํด ์ด๋ฒคํธ 4์ข :
ApplicationStartingEvent โ ์ ํ๋ฆฌ์ผ์ด์
์์ApplicationEnvironmentPreparedEvent โ ํ๊ฒฝ ์ ๋ณด ์ค๋นApplicationContextInitializedEvent โ ์ปจํ
์คํธ ์ด๊ธฐํApplicationReadyEvent โ ๋ชจ๋ ์ค๋น ์๋ฃ (์ฌ์ฉ ๊ถ์ฅ)๋ค๋ฅธ ๋์:
CommandLineRunner / ApplicationRunner ์ธํฐํ์ด์ค์๊ธฐ ์ ๊ฒ
๋ชฉํ: 6์ฃผ์ฐจ ACID์ 'I(Isolation)'๋ฅผ ๊น์ด ํํค์น๋ค. 3๊ฐ์ง ์ถฉ๋ โ 4๊ฐ์ง ๊ฒฉ๋ฆฌ ์์ค ๋งคํธ๋ฆญ์ค๋ฅผ ์์ฑํ๋ค.
์ ์ ์ง์: 6์ฃผ์ฐจ Phase 6 (ACID)
ํต์ฌ ๊ฐ๋
๊ฒฉ๋ฆฌ ์์ค (Isolation Level):
"ํธ๋์ญ์ ๋ผ๋ฆฌ ์ผ๋ง๋ ์๋ก ๊ณ ๋ฆฝ ๋์ด ์๋์ง์ ์์ค"
์ ํ์ํ๊ฐ:
ํธ๋ ์ด๋์คํ:
์๊ธฐ ์ ๊ฒ
์ ์ ์ง์: 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๋ ํ์์ ๊ฐ์ ๋ณธ ๊ฒ)
์๊ธฐ ์ ๊ฒ
์ ์ ์ง์: Unit 5.2
ํต์ฌ ์๋๋ฆฌ์ค
"๊ฐ์ ํธ๋์ญ์ ์์์ ๊ฐ์ ๋ฐ์ดํฐ๋ฅผ ๋ ๋ฒ ์ฝ์๋๋ฐ ๊ฐ์ด ๋ค๋ฆ"
์์ธ: ๋ค๋ฅธ ํธ๋์ญ์ ์ด ์์ /์ญ์
์์:
1. ํธ๋์ญ์
A: x ์กฐํ โ 10
2. ํธ๋์ญ์
B: x = 10 โ 50 ๋ณ๊ฒฝ ํ ์ปค๋ฐ
3. ํธ๋์ญ์
A: x ๋ค์ ์กฐํ โ 50 โ ๊ฐ์ ํธ๋์ญ์
์ธ๋ฐ ๋ค๋ฆ!
์ธ์ ๋ฌธ์ ์ธ๊ฐ:
์๊ธฐ ์ ๊ฒ
์ ์ ์ง์: Unit 5.3
ํต์ฌ ์๋๋ฆฌ์ค
"๊ฐ์ ์กฐ๊ฑด์ผ๋ก ๋ ๋ฒ ์กฐํํ๋๋ฐ ๊ฒฐ๊ณผ ํ ์๊ฐ ๋ค๋ฆ"
์์ธ: ๋ค๋ฅธ ํธ๋์ญ์ ์ด ์ฝ์ (๋๋ ์ญ์ )
์์:
1. ํธ๋์ญ์
A: ์์ก โฅ 100๋ง ์กฐ๊ฑด์ผ๋ก ์กฐํ โ 5๊ฑด
2. ํธ๋์ญ์
B: ์์ก 200๋ง ์ ๊ท ๊ณ์ข INSERT ํ ์ปค๋ฐ
3. ํธ๋์ญ์
A: ๊ฐ์ ์กฐ๊ฑด ๋ค์ ์กฐํ โ 6๊ฑด โ "์ ๋ น" ํ ๋ฑ์ฅ
Non-repeatable Read์์ ์ฐจ์ด:
์๊ธฐ ์ ๊ฒ
์ ์ ์ง์: Unit 5.2~5.4
ํต์ฌ ๋งคํธ๋ฆญ์ค:
| ๊ฒฉ๋ฆฌ ์์ค | Dirty Read | Non-repeatable Read | Phantom 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:
Level 2 โ REPEATABLE READ โญ:
Level 3 โ SERIALIZABLE:
Spring์์ ๊ฒฉ๋ฆฌ ์์ค ์ง์ :
@Transactional(isolation = Isolation.REPEATABLE_READ)
public void method() { ... }
์๊ธฐ ์ ๊ฒ
โ โ โ ๋ฉด์ ๋จ๊ณจ (๋ฐ๋์):
โ โ ๋งค์ฐ ๊ถ์ฅ:
[ ] 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๋ฌธํญ ํต๊ณผ
internal call ํจ์ ๊ณผ @PostConstruct ํจ์ ์ ๊ฐ์ ๋ณธ์ง์ ๋ ์ผ๊ตด:
| 9์ฃผ์ฐจ internal call | 10์ฃผ์ฐจ @PostConstruct | |
|---|---|---|
| ๋ณธ์ง | ํ๋ก์๋ฅผ ๊ฑฐ์น์ง ์๋ ํธ์ถ | ํ๋ก์๊ฐ ์์ง ๋ง๋ค์ด์ง์ง ์์ |
| ์์ | ๋ฐํ์, this ํธ์ถ ์ | ๋น ์ด๊ธฐํ ์์ |
| ์ฆ์ | @Transactional ๋ฌด์ | @Transactional ๋ฌด์ |
| ํด๊ฒฐ | ํด๋์ค ๋ถ๋ฆฌ | ApplicationReadyEvent |
โ ๋ ํจ์ ์ ํจ๊ป ๋ฌถ์ด ์ธ์์ผ ํ๋ค (๋ฉด์ ๋น์ถ).
Phase 4 ์ค์ต:
TransactionSynchronizationManager.isActualTransactionActive() ๋ก ๊ฒ์ฆPhase 5 ์ค์ต:
SET TRANSACTION ISOLATION LEVEL ๋ช
๋ น์ผ๋ก ์์ค ๋ณ๊ฒฝํธ๋์ญ์ ํ์ต์ 5๋จ๊ณ ์๊ฒฐ:
โ ์ด์ ํธ๋์ญ์ ์ ๋ชจ๋ ๊ฒ์ ์๋ค. 11์ฃผ์ฐจ๋ถํฐ๋ ์ ์์ญ์ผ๋ก ์ง์ ํ ์์ .