Spring

[Spring] Transaction(ํŠธ๋žœ์žญ์…˜)

jeong_ii 2025. 1. 9. 18:02

๐Ÿ”น Transaction์ด๋ž€ ?

[ Transaction ํƒ„์ƒ ๋ฐฐ๊ฒฝ ]

๋ณต์žกํ•œ ํ”„๋กœ๊ทธ๋žจ์„ ๊ฐœ๋ฐœํ•˜๋‹ค ๋ณด๋ฉด ์ฟผ๋ฆฌ ํ•œ ์ค„๋กœ ํ•ด๊ฒฐํ•  ์ˆ˜ ์—†๋Š” ๋กœ์ง์„ ์ฒ˜๋ฆฌํ•ด์•ผ ํ•˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ๋งŽ๋‹ค.

์—ฌ๋Ÿฌ ๊ฐœ์˜ ์ฟผ๋ฆฌ๊ฐ€ ์ฒ˜๋ฆฌ๋˜๋Š” ์ƒํ™ฉ์—์„œ ๋ฌธ์ œ๊ฐ€ ์ƒ๊ฒจ๋ฒ„๋ฆฐ๋‹ค๋ฉด ์‹œ์Šคํ…œ์— ํฐ ๊ฒฐํ•จ์„ ๋‚จ๊ธฐ๊ฒŒ ๋œ๋‹ค.

 

์˜ˆ๋ฅผ ๋“ค์–ด, ์‡ผํ•‘๋ชฐ ์„œ๋น„์Šค๋ฅผ ๊ตฌํ˜„ํ•  ๋•Œ, ์•„๋ž˜์™€ ๊ฐ™์€ ๋กœ์ง์€ ํ•œ ์ค„๋กœ ์ฒ˜๋ฆฌํ•˜๋Š” ๊ฒƒ์ด ๋ถˆ๊ฐ€๋Šฅํ•˜๋‹ค.

 

๋จผ์ € ์‡ผํ•‘๋ชฐ์—์„œ ์ƒํ’ˆ์„ ๊ตฌ๋งคํ•  ๋•Œ, ํšŒ์›์˜ ์ž”์—ฌ ๊ธˆ์•ก์ด ์ถฉ๋ถ„ํ•œ์ง€ ํ™•์ธํ•˜๊ณ  ์ž”์—ฌ ๊ธˆ์•ก์ด ์ƒํ’ˆ ๊ฐ€๊ฒฉ๋ณด๋‹ค ๋†’์„ ๋•Œ ๊ตฌ๋งค ๋กœ์ง์œผ๋กœ ๋„˜์–ด๊ฐ€์•ผ ํ•œ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ์ƒํ’ˆ์˜ ์žฌ๊ณ ๊ฐ€ ์žˆ๋Š”์ง€ ํ™•์ธ ํ›„์— ํšŒ์›์˜ ์ž”์—ฌ ๊ธˆ์•ก์—์„œ ์ƒํ’ˆ ๊ธˆ์•ก๋งŒํผ ๊ฐ์†Œ์‹œํ‚ค๊ณ  ๋กœ์ง์„ ์ข…๋ฃŒํ•ด์•ผ ํ•œ๋‹ค.

 

๊ทธ๋Ÿฐ๋ฐ ์„ ํƒ ์ƒํ’ˆ ๊ตฌ๋งค ๋‹จ๊ณ„์—์„œ Exception()์ด ๋ฐœ์ƒํ•˜์—ฌ ์ƒํ’ˆ์ด ์—†์Œ์—๋„ ๋ถˆ๊ตฌํ•˜๊ณ  ์ƒํ’ˆ์ด ์žˆ๋‹ค๊ณ  ํŒ๋‹จํ•˜๊ฑฐ๋‚˜,

์ž”์—ฌ ๊ธˆ์•ก์ด ๊ฐ์†Œํ•˜๋Š” ์ฐฐ๋‚˜์— ์„œ๋ฒ„์˜ ์ „์›์ด ๋‚˜๊ฐ€ ์ƒํ’ˆ์„ ๊ตฌ๋งคํ–ˆ๋Š”๋ฐ๋„ ํšŒ์›์˜ ์ž”์—ฌ ๊ธˆ์•ก์ด ๊ฐ์†Œํ•˜์ง€ ์•Š์„ ์ˆ˜ ์žˆ๋‹ค.

์ด๋Ÿฌํ•œ ์ƒํ™ฉ์€ ์—„์ฒญ๋‚œ ๋น„์šฉ ์†์‹ค์„ ์œ ๋ฐœํ•˜๋Š”๋ฐ, ์ด๋Ÿฌํ•œ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด Transaction ๊ธฐ์ˆ ์ด ํƒ„์ƒํ•˜๊ฒŒ ๋˜์—ˆ๋‹ค.

 

[ Transaction ๊ธฐ๋ณธ ๋ฐฉ๋ฒ• ]

Transaction์€ 2๊ฐœ ์ด์ƒ์˜ ์ฟผ๋ฆฌ๋ฅผ ํ•˜๋‚˜์˜ ์ปค๋„ฅ์…˜(Connection)์œผ๋กœ ๋ฌถ์–ด DB์— ์ „์†กํ•˜๊ณ , ์ด ๊ณผ์ •์—์„œ ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•  ๊ฒฝ์šฐ ์ž๋™์œผ๋กœ ๋ชจ๋“  ๊ณผ์ •์„ ์›๋ž˜๋Œ€๋กœ ๋˜๋Œ๋ ค ๋†“๋Š”๋‹ค. ์ด๋Ÿฌํ•œ ๊ณผ์ •์„ ๊ตฌํ˜„ํ•˜๊ธฐ ์œ„ํ•ด Transaction์€ ํ•˜๋‚˜ ์ด์ƒ์˜ ์ฟผ๋ฆฌ๋ฅผ ์ฒ˜๋ฆฌํ•  ๋•Œ ๋™์ผํ•œ ์ปค๋„ฅ์…˜(Connection) ๊ฐ์ฒด๋ฅผ ๊ณต์œ ํ•˜๋„๋ก ํ•œ๋‹ค.

 

 

๐Ÿ”น Spring์—์„œ Transaction ์‚ฌ์šฉ๋ฐฉ๋ฒ•

[ Spring์—์„œ Transaction ]

Spring์€ ์ฝ”๋“œ ๊ธฐ๋ฐ˜์˜ ํŠธ๋žœ์žญ์…˜(Programmatic Transaction) ์ฒ˜๋ฆฌ๋ฟ ์•„๋‹ˆ๋ผ ์„ ์–ธ์  ํŠธ๋žœ์žญ์…˜(Declarative Transaction)์„ ์ง€์›ํ•˜๊ณ  ์žˆ๋‹ค. Spring์—์„œ ์ œ๊ณตํ•˜๋Š” ํŠธ๋žœ์žญ์…˜ ํ…œํ”Œ๋ฆฟ ํด๋ž˜์Šค๋ฅผ ์ด์šฉํ•˜๊ฑฐ๋‚˜ ์„ค์ • ํŒŒ์ผ, ์–ด๋…ธํ…Œ์ด์…˜์„ ์ด์šฉํ•ด ํŠธ๋žœ์žญ์…˜์˜ ๋ฒ”์œ„ ๋ฐ ๊ทœ์น™์„ ์ •์˜ํ•  ์ˆ˜ ์žˆ๋‹ค.

Spring์—์„œ๋Š” ์ฃผ๋กœ ์„ ์–ธ์  ํŠธ๋žœ์žญ์…˜์„ ์ด์šฉํ•˜๋Š”๋ฐ, <tx:advice> ํƒœ๊ทธ ๋˜๋Š” @Transactional ์–ด๋…ธํ…Œ์ด์…˜์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

์ด๋•Œ ์ฟผ๋ฆฌ๋ฌธ์„ ์ฒ˜๋ฆฌํ•˜๋Š” ๊ณผ์ •์—์„œ ์—๋Ÿฌ๊ฐ€ ๋‚ฌ์„ ๊ฒฝ์šฐ ์ž๋™์œผ๋กœ Rollback ์ฒ˜๋ฆฌ๋ฅผ ํ•ด์ค€๋‹ค.

 

[ @Transactional ]

์ผ๋ฐ˜์ ์œผ๋กœ Spring์—์„œ๋Š” Service Layer์—์„œ @Transactional์„ ์ถ”๊ฐ€ํ•˜์—ฌ ํŠธ๋žœ์žญ์…˜ ์ฒ˜๋ฆฌ๋ฅผ ํ•œ๋‹ค.

package com.spring.store.service;

import com.spring.store.dto.StoreDTO;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;

public interface StoreService {
    List<StoreDTO> selectStoreInfoList(StoreDTO storeDTO);
    StoreDTO selectStoreInfo(StoreDTO storeDTO);
    int insertStoreInfo(StoreDTO storeDTO);
    int updateStoreInfo(StoreDTO storeDTO);
    int deleteStoreInfo(StoreDTO storeDTO);
}
package com.spring.store.service.impl;

import com.spring.store.dto.StoreDTO;
import com.spring.store.service.StoreService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;

@Service
public class StoreServiceImpl implements StoreService {
    @Override
    public List<StoreDTO> selectStoreInfoList(StoreDTO storeDTO) {
        return null; // ๋ฐ์ดํ„ฐ ์กฐํšŒ ๋กœ์ง ๊ตฌํ˜„
    }

    @Override
    public StoreDTO selectStoreInfo(StoreDTO storeDTO) {
        return null; // ๋ฐ์ดํ„ฐ ์กฐํšŒ ๋กœ์ง ๊ตฌํ˜„
    }

    @Transactional
    @Override
    public int insertStoreInfo(StoreDTO storeDTO) {
        return 0; // ๋ฐ์ดํ„ฐ ์‚ฝ์ž… ๋กœ์ง ๊ตฌํ˜„
    }

    @Transactional
    @Override
    public int updateStoreInfo(StoreDTO storeDTO) {
        return 0; // ๋ฐ์ดํ„ฐ ์ˆ˜์ • ๋กœ์ง ๊ตฌํ˜„
    }

    @Transactional
    @Override
    public int deleteStoreInfo(StoreDTO storeDTO) {
        return 0; // ๋ฐ์ดํ„ฐ ์‚ญ์ œ ๋กœ์ง ๊ตฌํ˜„
    }
}

์œ„ ์˜ˆ์ œ์—์„œ๋Š” ๋ฐ์ดํ„ฐ ์กฐํšŒ๋งŒ ์ˆ˜ํ–‰ํ•˜๋Š” select ๋ฉ”์„œ๋“œ์—๋Š” @Transactional๋ฅผ ์ ์šฉํ•˜์ง€ ์•Š์•˜๊ณ ,

๋ฐ์ดํ„ฐ๋ฅผ ๋ณ€๊ฒฝํ•˜๋Š” insert, update, delete ๋ฉ”์„œ๋“œ์—๋งŒ @Transactional์„ ์ ์šฉํ•˜์—ฌ ํŠธ๋žœ์žญ์…˜์„ ์„ค์ •ํ–ˆ๋‹ค. 

 

์กฐํšŒ ๋ฉ”์„œ๋“œ๋Š” ํŠธ๋žœ์žญ์…˜์ด ํ•„์ˆ˜์ ์ด์ง€ ์•Š์ง€๋งŒ, ์ฝ๊ธฐ ์ „์šฉ ํŠธ๋žœ์žญ์…˜(@Transactional(readOnly = true))์„ ์ ์šฉํ•˜๋ฉด ์„ฑ๋Šฅ ์ตœ์ ํ™”๊ฐ€ ๊ฐ€๋Šฅํ•˜๋‹ค.

๋ฐ˜๋ฉด, insert, update, delete ๊ฐ™์€ ๋ฐ์ดํ„ฐ ๋ณ€๊ฒฝ์ด ๋ฐœ์ƒํ•˜๋Š” ๋ฉ”์„œ๋“œ์—๋Š” ํŠธ๋žœ์žญ์…˜์„ ์ ์šฉํ•˜๋ฉด ์˜ˆ์™ธ ๋ฐœ์ƒ ์‹œ ์ž๋™์œผ๋กœ ๋กค๋ฐฑ(rollback) ๋˜๋„๋ก ์„ค์ •ํ•  ์ˆ˜ ์žˆ๋‹ค.

 

๋˜ํ•œ, @Transactional์€ ์ธํ„ฐํŽ˜์ด์Šค๊ฐ€ ์•„๋‹Œ ๊ตฌํ˜„ ํด๋ž˜์Šค์— ์ ์šฉํ•˜๋Š” ๊ฒƒ์ด ์ผ๋ฐ˜์ ์ด๋‹ค.

์ด๋Š” Spring์˜ AOP ๊ธฐ๋ฐ˜ ํŠธ๋žœ์žญ์…˜ ๊ด€๋ฆฌ ๋ฐฉ์‹ ๋•Œ๋ฌธ์ด๋ฉฐ, ์ธํ„ฐํŽ˜์ด์Šค์— ์ ์šฉํ•  ๊ฒฝ์šฐ ํŠธ๋žœ์žญ์…˜์ด ์ •์ƒ์ ์œผ๋กœ ์ž‘๋™ํ•˜์ง€ ์•Š์„ ์ˆ˜ ์žˆ๋‹ค.