๐Ÿ“Œ Spring Transaction ์™„๋ฒฝ ์ดํ•ด

My Pale Blue Dotยท2025๋…„ 4์›” 28์ผ
0

SPRING

๋ชฉ๋ก ๋ณด๊ธฐ
20/36
post-thumbnail

๐Ÿ“Œ Spring Transaction ์™„๋ฒฝ ์ดํ•ด

๐Ÿ“… ๋‚ ์งœ

2025-04-28


๐Ÿ“ ํ•™์Šต ๋‚ด์šฉ

1๏ธโƒฃ Spring Transaction ๊ฐœ๋…

  • ์Šคํ”„๋ง ํŠธ๋žœ์žญ์…˜์€ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์ž‘์—…์˜ ์ผ๊ด€์„ฑ(Consistency), ๋ฌด๊ฒฐ์„ฑ(Integrity), ์›์ž์„ฑ(Atomicity)์„ ๋ณด์žฅ.
  • ์—ฌ๋Ÿฌ ์ž‘์—…์„ ํ•˜๋‚˜์˜ ๋‹จ์œ„๋กœ ๋ฌถ์–ด ์ฒ˜๋ฆฌํ•˜๋ฉฐ, ์˜ˆ์™ธ ๋ฐœ์ƒ ์‹œ Rollback์œผ๋กœ ๋ฐ์ดํ„ฐ ์˜ค๋ฅ˜๋ฅผ ๋ฐฉ์ง€.
  • ์ฃผ์š” ์–ด๋…ธํ…Œ์ด์…˜: @Transactional

2๏ธโƒฃ @Transactional ์ฃผ์š” ์†์„ฑ ์ •๋ฆฌ

์†์„ฑ์„ค๋ช…์˜ˆ์‹œ๊ฐ’
propagationํŠธ๋žœ์žญ์…˜ ์ „ํŒŒ ๋ฐฉ์‹ ์„ค์ •๊ธฐ์กด ํŠธ๋žœ์žญ์…˜์ด ์žˆ์„ ๋•Œ ์ƒˆ๋กœ์šด ํŠธ๋žœ์žญ์…˜ ์ƒ์„ฑ ์—ฌ๋ถ€ ๊ฒฐ์ •REQUIRED, REQUIRES_NEW ๋“ฑ
isolationํŠธ๋žœ์žญ์…˜ ๊ฒฉ๋ฆฌ ์ˆ˜์ค€ ์„ค์ •๋™์‹œ์„ฑ ์ฒ˜๋ฆฌ ์‹œ ๋ฐ์ดํ„ฐ ์ผ๊ด€์„ฑ ์œ ์ง€READ_COMMITTED, SERIALIZABLE
timeoutํŠธ๋žœ์žญ์…˜ ์ตœ๋Œ€ ์ˆ˜ํ–‰ ์‹œ๊ฐ„ ์„ค์ •์‹œ๊ฐ„ ์ดˆ๊ณผ ์‹œ ์ž๋™ ๋กค๋ฐฑ์ดˆ ๋‹จ์œ„(์˜ˆ: timeout = 30)
readOnly์ฝ๊ธฐ ์ „์šฉ ํŠธ๋žœ์žญ์…˜ ์—ฌ๋ถ€ ์„ค์ •์„ฑ๋Šฅ ์ตœ์ ํ™” ๋ชฉ์ true / false
rollbackFor๋กค๋ฐฑ ๋Œ€์ƒ ์˜ˆ์™ธ ์ง€์ •rollbackFor = Exception.class
noRollbackFor๋กค๋ฐฑ ์ œ์™ธ ์˜ˆ์™ธ ์ง€์ •noRollbackFor = CustomException.class

3๏ธโƒฃ ์˜์กด์„ฑ ์„ค์ • (pom.xml)

<!-- Spring Transaction -->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-tx</artifactId>
    <version>${org.springframework-version}</version>
</dependency>

4๏ธโƒฃ ํŠธ๋žœ์žญ์…˜ ์„ค์ • ํด๋ž˜์Šค

@Configuration
@EnableTransactionManagement
public class TxConfig {

	@Autowired
	private DataSource dataSource3;

    @Bean
    public DataSourceTransactionManager transactionManager() {
        return new DataSourceTransactionManager(dataSource3);
    }
}

5๏ธโƒฃ HikariCP DataSource ์„ค์ •

@Bean
public HikariDataSource dataSource3() {
    HikariDataSource dataSource = new HikariDataSource();
    dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");
    dataSource.setJdbcUrl("jdbc:mysql://localhost:3306/testdb");
    dataSource.setUsername("root");
    dataSource.setPassword("1234");
    return dataSource;
}

6๏ธโƒฃ Service ๊ณ„์ธต ํŠธ๋žœ์žญ์…˜ ์ ์šฉ ์˜ˆ์ œ

@Transactional(
    propagation = Propagation.REQUIRED,
    isolation = Isolation.READ_COMMITTED,
    timeout = 30,
    readOnly = false,
    rollbackFor = Exception.class
)
public void addMemoTx(MemoDto dto) {
    log.info("MemoService's addMemoTx Call! ");
    int id = dto.getId();
    memoMapper.insert(dto);
    dto.setId(id);
    memoMapper.insert(dto);
}

๐Ÿ”น ํŠธ๋žœ์žญ์…˜ ๋™์ž‘ ์š”์•ฝ

  • ์˜ˆ์™ธ ๋ฐœ์ƒ ์‹œ ๋ชจ๋“  ์ž‘์—…์ด ๋กค๋ฐฑ.
  • ์„ค์ •๋œ timeout ๋‚ด ์™„๋ฃŒ๋˜์ง€ ์•Š์œผ๋ฉด ์ž๋™ ๋กค๋ฐฑ.
  • ์ฝ๊ธฐ ์ „์šฉ ์„ค์ • ์‹œ ์ฟผ๋ฆฌ ์ตœ์ ํ™” ๊ฐ€๋Šฅ.

๐Ÿ”ฅ ์ •๋ฆฌ

  • ํŠธ๋žœ์žญ์…˜ ์†์„ฑ์„ ์ ์ ˆํžˆ ํ™œ์šฉํ•˜๋ฉด ๋ฐ์ดํ„ฐ ์•ˆ์ •์„ฑ๊ณผ ์„ฑ๋Šฅ์„ ๋ชจ๋‘ ํ™•๋ณดํ•  ์ˆ˜ ์žˆ์Œ.
  • @Transactional์€ ๋‹จ์ˆœํžˆ ์„ ์–ธํ•˜๋Š” ๊ฒƒ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ, ์ƒํ™ฉ์— ๋งž๋Š” ์†์„ฑ ์„ค์ •์ด ์ค‘์š”.
  • ํŠธ๋žœ์žญ์…˜์„ ์ ์šฉํ•˜์ง€ ์•Š์œผ๋ฉด ์˜ˆ์™ธ ๋ฐœ์ƒ ์‹œ ๋ฐ์ดํ„ฐ๊ฐ€ ๋ถ€๋ถ„์ ์œผ๋กœ ์ €์žฅ๋  ์œ„ํ—˜์ด ์žˆ์Œ.

๐Ÿ”— ์ฐธ๊ณ  ์ž๋ฃŒ


profile
Here, My Pale Blue.๐ŸŒ

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