//
Search
๐Ÿ“ฉ

DataSource, TransactionManager

DataSource

๋ฌผ๋ฆฌ์ ์—” ๋ฐ์ดํ„ฐ์†Œ์Šค(๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค) ์ •๋ณด๋ฅผ ๋‹ด๋Š” ์ธํ„ฐํŽ˜์ด์Šค
โ€ข
ํ•˜๋‚˜์˜ ๋ฌผ๋ฆฌ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋ฅผ ํ‘œํ˜„
โ€ข
๋‹ค์–‘ํ•œ ๊ตฌํ˜„์ฒด๋ฅผ ์‚ฌ์šฉ

TransactionManager

์Šคํ”„๋ง ํŠธ๋žœ์žญ์…˜ ๊ด€๋ฆฌ ๊ธฐ๋Šฅ์„ ๋‹ด๋‹นํ•˜๋Š” ์ธํ„ฐํŽ˜์ด์Šค
โ€ข
์šฉ๋„์— ๋”ฐ๋ผ ๋‹ค์–‘ํ•œ ์ธํ„ฐํŽ˜์ด์Šค์™€ ๊ตฌํ˜„์ฒด๋“ค

JPA DB ์ˆ˜๋™ ์„ค์ •(java code)

์—ฌํƒœ DataSource๋‚˜ TransactionManager๋ฅผ ์ž๋ฐ” ์ฝ”๋“œ๋กœ ์ž‘์„ฑํ•  ์ผ์€ ์—†์—ˆ๋‹ค. ํ•˜์ง€๋งŒ
์ž๋ฐ” ์ฝ”๋“œ๋กœ DataSource, TransactionManager๋ฅผ ์ˆ˜๋™ ์„ธํŒ…ํ•ด์•ผ ํ•˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ์žˆ๋‹ค.
โ€ข
์–ธ์ œ?
โ—ฆ
configuration properties๋กœ ์ปค๋ฒ„๋˜์ง€ ์•Š๋Š” ์„ธ๋ฐ€ํ•œ ์˜ต์…˜์„ ์ค„ ๋•Œ
โ—ฆ
๋‹ค์ค‘ DataSource(ํฐ ํ”„๋กœ์ ํŠธ๋‚˜ ๋ ˆ๊ฑฐ์‹œ)
โ€ข
์„ธํŒ…ํ•ด์•ผ ํ•˜๋Š” ์š”์†Œ
โ—ฆ
DataSource
โ—ฆ
EntityManagerFactory โ†’LocalContainerEntityManagerFactoryBean
โ–ช
์ถ”๊ฐ€์ ์ธ ์˜ˆ์™ธ ์ฒ˜๋ฆฌ ๊ธฐ๋Šฅ ๋•Œ๋ฌธ์—, ์ธํ„ฐํŽ˜์ด์Šค ๋ง๊ณ  ๊ตฌํ˜„์ฒด๋ฅผ ์ง์ ‘ ๋นˆ์œผ๋กœ ๋“ฑ๋กํ•ด์•ผ ํ•œ๋‹ค
์ผ๋ฐ˜์  Bean ๋“ฑ๋ก @Bean public DataSource dataSource() { return ๊ตฌํ˜„์ฒด; } ํ•˜์ง€๋งŒ LocalContainerEntityManagerFactoryBean์€ @Bean public LocalContainerEntityManagerFactoryBean entityManagerFactory() { return new LocalContainerEntityManagerFactoryBean() }
Java
๋ณต์‚ฌ
โ—ฆ
PlatformTransactionManager
โ€ข
์„ธํŒ… ๊ตฌ์„ฑ: DataSource(DB ์„ค์ •) โ†’ EntityManagerFactory(JPA ์—”ํ‹ฐํ‹ฐ ๊ด€๋ฆฌ) โ†’ PlatformTransactionManager(ํŠธ๋žœ์žญ์…˜ ๊ด€๋ฆฌ)
@Configuration @EnableJpaRepositories @EnableTransactionManagement class ApplicationConfig { @Bean public DataSource dataSource() { EmbeddedDatabaseBuilder builder = new EmbeddedDatabaseBuilder(); return builder.setType(EmbeddedDatabaseType.H2).build(); } /* //jdbc @CofigurationProperties("spring.datasource") public DataSource dataSource() { return new DataSourceBuilder.create().build(); } */ @Bean public LocalContainerEntityManagerFactoryBean entityManagerFactory() { HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter(); vendorAdapter.setGenerateDdl(true); LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean(); factory.setJpaVendorAdapter(vendorAdapter); factory.setPackagesToScan("com.acme.domain"); factory.setDataSource(dataSource()); return factory; } @Bean public PlatformTransactionManager transactionManager(EntityManagerFactory entityManagerFactory) { JpaTransactionManager txManager = new JpaTransactionManager(); txManager.setEntityManagerFactory(entityManagerFactory); return txManager; } }
Java
๋ณต์‚ฌ

@Transactional

์Šคํ”„๋ง์ด ์• ๋…ธํ…Œ์ด์…˜ ๊ธฐ๋ฐ˜ ํŠธ๋žœ์žญ์…˜ ๊ด€๋ฆฌ ๊ธฐ๋Šฅ์„ ์ œ๊ณต
โ€ข
EntityManager ๋ถˆ๋Ÿฌ์˜ค๊ณ  โ†’ ๊ตฌ์—ญ ์ง€์ •ํ•˜๊ณ  โ†’ commit(), rollback() ์ง์ ‘ ํ•  ํ•„์š” ์—†๋‹ค!
โ€ข
์„œ๋น„์Šค ํด๋ž˜์Šค, ๋ฉ”์†Œ๋“œ์— ์ ์šฉํ•˜๋Š” ๊ฒƒ์œผ๋กœ ๊ฐ„๋‹จํžˆ ํŠธ๋žœ์žญ์…˜ ๊ตฌ์—ญ์„ ์„ค์ •
โ—ฆ
๋™์‹œ์— ์„ค์ •ํ•˜๋ฉด ๋ฉ”์†Œ๋“œ๊ฐ€ ์šฐ์„ ์ˆœ์œ„
โ€ข
JpaRepository๋Š” ๋ฉ”์†Œ๋“œ ๋‹จ์œ„ @Transactional์ด ์ด๋ฏธ ๋ถ™์–ด์žˆ์Œ
โ€ข
๊ด€๋ จ ์• ๋…ธํ…Œ์ด์…˜
โ—ฆ
์Šคํ”„๋ง ํ…Œ์ŠคํŠธ ์ง€์› ์• ๋…ธํ…Œ์ด์…˜: @DataJpaTest ์™€ ์ข‹์€ ๊ถํ•ฉ
โ—ฆ
@Commit
โ—ฆ
@Rollback
โ€ข
javax.transaction.@Transactional: ์Šคํ”„๋ง ํŒจํ‚ค์ง€๊ฐ€ ์•„๋‹˜, ๊ธฐ๋Œ€ํ•˜๋Š” ๊ธฐ๋Šฅ์„ ์ฃผ์ง€ ์•Š์œผ๋ฏ€๋กœ ์ฃผ์˜

@Transactional: attributes

@Transactional์ด ์ œ๊ณตํ•˜๋Š” ๋‹ค์–‘ํ•œ ์˜ต์…˜๋“ค
โ€ข
transactionManager(value): ์‚ฌ์šฉํ•  ํŠธ๋žœ์žญ์…˜ ๋งค๋‹ˆ์ €๋ฅผ ์ด๋ฆ„์œผ๋กœ ํŠน์ •
โ€ข
label: ํŠธ๋žœ์žญ์…˜ ๊ตฌ๋ถ„ ์ง“๋„ ์‹๋ณ„ํ•˜๋Š” ๋ ˆ์ด๋ธ”
โ€ข
propagation: ํŠธ๋žœ์žญ์…˜์ด ์ค‘์ฒฉ๋  ๊ฒฝ์šฐ ๋™์ž‘(ํŠธ๋žœ์žญ์…˜ ํšจ๊ณผ์˜ ์ „ํŒŒ) ๊ทœ์น™(dafalut: REQUIRED)
โ€ข
isolation: ํŠธ๋žœ์žญ์…˜ ๋‚ด๋ถ€ ๋ฐ์ดํ„ฐ์˜ ๊ฒฉ๋ฆฌ ๋ ˆ๋ฒจ
โ€ข
timeout, tumeoutString: ์‹œ๊ฐ„ ์ œํ•œ์„ ๊ฑฐ๋Š” ๊ฒƒ์ด ๊ฑฐ๋Šฅ
โ€ข
readOnly: ์ด ํŠธ๋žœ์žญ์…˜ ์•ˆ์—์„œ๋Š” select๋งŒ ์ผ์–ด๋‚œ๋‹ค๋ฅผ ํ‘œํ˜„
โ€ข
rollbackFor, rollbackForClassName
โ€ข
noRollbackFor, noRollbackForClassName

@Transactional:Propagation

์ค‘์ฒฉ๋œ ํŠธ๋žœ์žญ์…˜์˜ ๋™์ž‘ ๊ทœ์น™
โ€ข
REQUIRED(default): ํ˜„์žฌ ์žˆ์œผ๋ฉด ๋ณด์กฐ, ์—†์œผ๋ฉด ์ƒˆ๋กœ ๋งŒ๋“ค๊ธฐ
โ€ข
SUPPORTS: ํ˜„์žฌ ์žˆ์œผ๋ฉด ๋ณด์กฐ, ์—†์œผ๋ฉด ํŠธ๋žœ์žญ์…˜ ์—†์ด ์‹คํ–‰
โ€ข
MANDATORY: ์žˆ์œผ๋ฉด ๋ณด์กฐ, ์—†์œผ๋ฉด ์˜ˆ์™ธ ์ฒ˜๋ฆฌ
โ€ข
REQUIRED_NEW: ํŠธ๋žœ์žญ์…˜ ์ƒ์„ฑํ•˜๊ณ  ์‹คํ–‰, ํ˜„์žฌ ์žˆ๋˜ ๊ฒƒ์€ ๋ฏธ๋ฃธ
โ€ข
NOT_SUPPORTED: ํŠธ๋žœ์žญ์…˜ ์—†์ด ์‹คํ–‰, ํ˜„์žฌ ์žˆ๋˜ ๊ฒƒ์€ ๋ฏธ๋ฃธ
โ€ข
NEVER: ํŠธ๋žœ์žญ์…˜ ์—†์ด ์‹คํ–‰, ํ˜„์žฌ ํŠธ๋žœ์žญ์…˜์ด ์žˆ์—ˆ์œผ๋ฉด ์˜ˆ์™ธ ์ฒ˜๋ฆฌ
โ€ข
NESTED: ํ˜„์žฌ ์žˆ์œผ๋ฉด ๊ทธ ์•ˆ์—์„œ ์ค‘์ฒฉ๋œ ํŠธ๋žœ์žญ์…˜ ํ˜•์„ฑ

@Transactional:Isolation

ํŠธ๋žœ์žญ์…˜ ๋‚ด๋ถ€ ๋ฐ์ดํ„ฐ์˜ ๊ฒฉ๋ฆฌ ์ˆ˜์ค€
โ€ข
DEFAULT: ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์—๊ฒŒ ๋งก๊น€
โ€ข
READ_UNCOMMITED: dirty read + non-repeatable read + phantom read
โ€ข
READ_COMMITED: non-repeatable read + phantom read
โ€ข
REPEATABLE_READ: phantom read
โ€ข
SERIALIZABLE: ์™„์ „ ์ง๋ ฌ ์ˆ˜ํ–‰