๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
๊ฐœ์ธ ๊ณต๋ถ€/DB

[jdbc] ํŠธ๋žœ์žญ์…˜ ๊ด€๋ฆฌ (feat. ์Šคํ”„๋ง ํ”„๋ ˆ์ž„์›Œํฌ)

by syLim___ 2025. 2. 5.
728x90

๐Ÿ“‘ ์ด์ „ ๊ธ€: ํŠธ๋žœ์žญ์…˜

โœ… ์ž๋ฐ” ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ ํŠธ๋žœ์žญ์…˜ ๊ด€๋ฆฌ

ํŠธ๋žœ์žญ์…˜์€ ๋น„์ง€๋‹ˆ์Šค ๋กœ์ง์ด ์žˆ๋Š” ์„œ๋น„์Šค ๊ณ„์ธต์—์„œ ์‹œ์ž‘ํ•ด์•ผ ํ•œ๋‹ค.

๋น„์ง€๋‹ˆ์Šค ๋กœ์ง์—์„œ ๋ฌธ์ œ๊ฐ€ ์ƒ๊ธฐ๋ฉด, ๋ฌธ์ œ๊ฐ€ ์ƒ๊ธด ๋ถ€๋ถ„์œผ๋กœ ์ธํ•ด ์‹คํ–‰์ทจ์†Œ๋˜์–ด์•ผ ํ•˜๋Š” ์ž‘์—…๋“ค์€ ์ „๋ถ€ ๋กค๋ฐฑํ•ด์•ผํ•˜๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

 

ํŠธ๋žœ์žญ์…˜์„ ์‹œ์ž‘ํ•˜๋ ค๋ฉด Connection์ด ์žˆ์–ด์•ผ ํ•œ๋‹ค!

์„œ๋น„์Šค ๊ณ„์ธต์—์„œ ํŠธ๋žœ์žญ์…˜์„ ์œ ์ง€ํ•˜๋ ค๋ฉด

์„œ๋น„์Šค ๊ณ„์ธต์—์„œ ์ปค๋„ฅ์…˜์„ ๋งŒ๋“ค๊ณ , ํŠธ๋žœ์žญ์…˜์— ๋๋‚  ๋•Œ๊นŒ์ง€ ๋™์ผํ•œ ์ปค๋„ฅ์…˜์„ ์œ ์ง€ํ•ด์•ผ ํ•œ๋‹ค.

 

๐Ÿ“Œ ๋ฌธ์ œ์ 

์œ ์ง€๋ณด์ˆ˜๋ฅผ ์œ„ํ•ด์„œ๋Š” ํ•˜๋‚˜์˜ ํด๋ž˜์Šค๊ฐ€ ๋ณ€๊ฒฝ๋  ๋•Œ ๋‚˜๋จธ์ง€ ํด๋ž˜์Šค๋“ค์˜ ๋ณ€๊ฒฝ์ด ์ตœ์†Œํ™”๋˜์–ด์•ผ ํ•œ๋‹ค.

 

์ฆ‰ UI๊ฐ€ ๋ฐ”๋€Œ๊ณ , ๋ฐ์ดํ„ฐ ์ €์žฅ ๊ธฐ์ˆ ์ด ๋ฐ”๋€๋‹ค๊ณ  ํ•˜๋”๋ผ๋„

ํ•ต์‹ฌ ๋น„์ง€๋‹ˆ์Šค ๋กœ์ง์ธ ์„œ๋น„์Šค ๊ณ„์ธต์€ ์ตœ๋Œ€ํ•œ ์ˆ˜์ •๋˜์ง€ ์•Š์•„์•ผ ํ•œ๋‹ค.

 

๊ทธ๋Ÿฐ๋ฐ ํŠธ๋žœ์žญ์…˜์„ ์„œ๋น„์Šค ๊ณ„์ธต์—์„œ ์‹œ์ž‘ํ•ด๋ฒ„๋ฆฌ๋ฉด

์„œ๋น„์Šค ๊ณ„์ธต์€ jdbc ๊ธฐ์ˆ ์— ์˜์กดํ•˜๊ฒŒ ๋œ๋‹ค.

 

๐Ÿš€ ์ฝ”๋“œ ์˜ˆ์‹œ

@RequiredArgsConstructor
public class MemberService {

    private final DataSource dataSource; // <- jdbc ๊ธฐ์ˆ 
    private final MemberRepository memberRepository;

    public  void accountTransfer(String fromId, String toId, int money) throws SQLException {
        Connection conn = dataSource.getConnection(); // <- jdbc ๊ธฐ์ˆ 
        try {
            conn.setAutoCommit(false); // ํŠธ๋žœ์žญ์…˜ ์‹œ์ž‘
            
            // ๊ณ„์ขŒ์ด์ฒด ์ž‘์—… (์ฝ”๋“œ ์ƒ๋žต)
            
            conn.commit(); // ์„ฑ๊ณต ์‹œ ์ปค๋ฐ‹

        } catch (Exception e) {
            conn.rollback(); // ์‹คํŒจ ์‹œ ๋กค๋ฐฑ
            throw new IllegalStateException(e);
        } finally {
            release(conn);
        }

    }
    
    ...
    
}

 

์ด๋ ‡๊ฒŒ ๋˜๋ฉด, ๋ฆฌํฌ์ง€ํ† ๋ฆฌ๊ฐ€ jdbc ๊ธฐ์ˆ ์„ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ฒŒ ๋œ๋‹ค๋ฉด

DataSource, Connection, SQLException ๋˜ํ•œ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ฒŒ ๋ ํ…Œ๋‹ˆ

์ด ๋ถ€๋ถ„๋“ค์„ ์ „๋ถ€ ์ˆ˜์ •ํ•ด์ฃผ์–ด์•ผ ํ•œ๋‹ค๋Š” ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค.

 

ํ•œ๋งˆ๋””๋กœ ํ•ต์‹ฌ ๋น„์ง€๋‹ˆ์Šค ๋กœ์ง๊ณผ jdbc ๊ธฐ์ˆ ์ด ์„ž์—ฌ์žˆ์–ด์„œ, ์œ ์ง€๋ณด์ˆ˜๊ฐ€ ํž˜๋“ค์–ด์ง„๋‹ค.

๊ทธ๋ฆฌ๊ณ  ์ฝ”๋“œ์˜ ์ค‘๋ณต๋„ ๋งŽ์•„์ง„๋‹ค. (๋‚˜๋จธ์ง€ ์„œ๋น„์Šค ๋ฉ”์„œ๋“œ๋“ค์—์„œ๋„, ์œ„ ์ฝ”๋“œ์—์„œ ์ƒ๋žต๋œ ๊ณ„์ขŒ์ด์ฒด ์ž‘์—… ๋ถ€๋ถ„(=์‹ค์ œ ๋น„์ง€๋‹ˆ์Šค ๋กœ์ง ๋ถ€๋ถ„)์„ ์ œ์™ธํ•˜๊ณ ๋Š” ๋ชจ๋“  ์ฝ”๋“œ๊ฐ€ ๊ฑฐ์˜ ๋˜‘๊ฐ™์„ ๊ฒƒ์ด๋‹ค!)

 

โœ… Spring framework์—์„œ๋Š” ํ•ด๊ฒฐ๋ฐฉ๋ฒ•์„ ์ œ๊ณตํ•œ๋‹ค.

์Šคํ”„๋ง์€ TransactionManager ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์ œ๊ณตํ•จ์œผ๋กœ์จ ํŠธ๋žœ์žญ์…˜ ๊ธฐ๋Šฅ์„ ์ถ”์ƒํ™”ํ•˜๊ณ  ์žˆ๋‹ค.

 

TransactionManager์˜ ํ•˜์œ„ ์ธํ„ฐํŽ˜์ด์Šค์ธ PlatformTransactionManager ์ธํ„ฐํŽ˜์ด์Šค๋Š”

jdbc ๊ธฐ์ˆ ์— ๋Œ€ํ•œ ํŠธ๋žœ์žญ์…˜์„ ์ถ”์ƒํ™”ํ•˜๊ณ  ์žˆ๊ณ , ์Šคํ”„๋ง์€ jdbc ๋“œ๋ผ์ด๋ฒ„์— ๋”ฐ๋ฅธ ๊ตฌํ˜„์ฒด๋“ค์„ ์ œ๊ณตํ•œ๋‹ค.

 

package org.springframework.transaction;
import org.springframework.lang.Nullable;

public interface PlatformTransactionManager extends TransactionManager {
  TransactionStatus getTransaction(@Nullable TransactionDefinition definition) throws transactionException;
  void commit(TransactionStatus status) throws TransactionException;
  void rollback(TransactionStatus status) throws TransactionException;
}

 

์ด ํŠธ๋žœ์žญ์…˜ ๋งค๋‹ˆ์ €๋Š” ThreadLocal์„ ์‚ฌ์šฉํ•ด์„œ ์ปค๋„ฅ์…˜์„ ์œ ์ง€ํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•ด์ฃผ๊ธฐ ๋•Œ๋ฌธ์—,

๋ฉ€ํ‹ฐ์“ฐ๋ ˆ๋“œ ์ƒํ™ฉ์—์„œ ์•ˆ์ „ํ•˜๊ฒŒ ์ปค๋„ฅ์…˜ ๋™๊ธฐํ™”๊ฐ€ ๊ฐ€๋Šฅํ•˜๋‹ค.

 

๋Œ€ํ‘œ์  ๊ตฌํ˜„์ฒด๋กœ๋Š” DataSourceTransactionManager๊ฐ€ ์žˆ๋‹ค.

 

๐Ÿ“Œ DataSourceTransactionManager ๋™์ž‘ ๋ฐฉ์‹

- Datasource๋ฅผ ํ†ตํ•ด ์ปค๋„ฅ์…˜์„ ์ƒ์„ฑํ•˜๊ณ  ํŠธ๋žœ์žญ์…˜์„ ์‹œ์ž‘ํ•œ๋‹ค.

- ํ•ด๋‹น ์ปค๋„ฅ์…˜์„ ํŠธ๋žœ์žญ์…˜ ๋™๊ธฐํ™” ๋งค๋‹ˆ์ €์—๊ฒŒ ๋ณด๊ด€ํ•œ๋‹ค. (์ฝ”๋“œ๋ฅผ ๋œฏ์–ด๋ณด๋‹ˆ ConnectionHolder๊ฐ€ ์ด ์—ญํ• ์„ ํ•˜๋Š”๊ฒƒ๊ฐ™์€๋ฐ ๋” ๊ณต๋ถ€ํ•ด๋ด์•ผ๊ฒ ๋‹ค)

- ๋ฆฌํฌ์ง€ํ† ๋ฆฌ๋Š” ํŠธ๋žœ์žญ์…˜ ๋™๊ธฐํ™” ๋งค๋‹ˆ์ €๊ฐ€ ๋ณด๊ด€ํ•˜๊ณ  ์žˆ๋Š” ์ปค๋„ฅ์…˜์„ ๊บผ๋‚ด์„œ ์‚ฌ์šฉํ•œ๋‹ค.

- ํŠธ๋žœ์žญ์…˜์ด ์ข…๋ฃŒ๋˜๋ฉด DataSourceTransactionManager๋Š” ํ•ด๋‹น ์ปค๋„ฅ์…˜์„ ์ข…๋ฃŒํ•˜๊ณ , ์ปค๋„ฅ์…˜์„ ๋ฐ˜ํ™˜ํ•œ๋‹ค.

 

 

โœ… TransactionTemplate์€ ์ฝ”๋“œ ์ค‘๋ณต ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•ด์ค€๋‹ค.

 

TransactionManager๋ฅผ ํ†ตํ•ด ํŠธ๋žœ์žญ์…˜์„ ์ถ”์ƒํ™”ํ•˜๋”๋ผ๋„ ์ฝ”๋“œ ์ค‘๋ณต ๋ฌธ์ œ๋Š” ์—ฌ์ „ํžˆ ์กด์žฌํ•œ๋‹ค.

์Šคํ”„๋ง ํ”„๋ ˆ์ž„์›Œํฌ์—์„œ๋Š” ์ด๊ฒƒ์„ ํ•ด๊ฒฐํ•ด์ฃผ๋Š” TransactionTemplate ํด๋ž˜์Šค๋ฅผ ์ œ๊ณตํ•œ๋‹ค.

(ํ…œํ”Œ๋ฆฟ ์ฝœ๋ฐฑ ํŒจํ„ด)

 

๐Ÿš€ ์ฝ”๋“œ ์˜ˆ์‹œ

@RequiredArgsConstructor
public class MemberService {

    private final TransactionTemplate transactionTemplate;
    private final MemberRepository memberRepository;
    
    public  void accountTransfer(String fromId, String toId, int money) throws SQLException {

        // ๋น„์ง€๋‹ˆ์Šค ๋กœ์ง๋งŒ ๋„˜๊ฒจ์ฃผ๋ฉด, ํ…œํ”Œ๋ฆฟ ์•ˆ์—์„œ ์•Œ์•„์„œ
        // ํŠธ๋žœ์žญ์…˜ ์‹œ์ž‘ํ•˜๊ณ , ์„ฑ๊ณต์‹œ ์ปค๋ฐ‹ ์‹คํŒจ์‹œ ๋กค๋ฐฑ ํ•˜๊ณ  ์ปค๋„ฅ์…˜ ๋ฐ˜ํ™˜๊นŒ์ง€ ํ•ด์ค€๋‹ค.
        transactionTemplate.executeWithoutResult((status) -> {
            try {
                bizLogic(fromId, toId, money);
            } catch (SQLException e) {
                throw new IllegalStateException(e);
            }
        });

    }
    ...
}

 

 

๐Ÿ“Œ ์—ฌ์ „ํžˆ ํ•ด๊ฒฐ๋˜์ง€ ์•Š๋Š” ๋ฌธ์ œ์ 

์—ฌ์ „ํžˆ ์„œ๋น„์Šค ๊ณ„์ธต์— ํŠธ๋žœ์žญ์…˜ ์ฒ˜๋ฆฌ ๋กœ์ง์ด ํฌํ•จ๋˜์–ด ์žˆ๋‹ค.

ํ•˜๋‚˜์˜ ํด๋ž˜์Šค์—์„œ '๋น„์ง€๋‹ˆ์Šค๋กœ์ง', 'ํŠธ๋žœ์žญ์…˜์ฒ˜๋ฆฌ' ๋ผ๋Š” ๋‘ ๊ฐ€์ง€ ๊ด€์‹ฌ์‚ฌ๋ฅผ ์ฒ˜๋ฆฌํ•˜๊ฒŒ ๋œ๋‹ค.

๊ฒฐ๊ณผ์ ์œผ๋กœ ์œ ์ง€๋ณด์ˆ˜๊ฐ€ ํž˜๋“ค์–ด์ง„๋‹ค.

 

๊ทธ๋ž˜์„œ ์Šคํ”„๋ง ํ”„๋ ˆ์ž„์›Œํฌ์—์„œ๋Š” ํŠธ๋žœ์žญ์…˜ AOP๋ฅผ ์ œ๊ณตํ•œ๋‹ค.

 

โœ… @Transactional

์Šคํ”„๋ง์—์„œ ์ œ๊ณตํ•˜๋Š” ํŠธ๋žœ์žญ์…˜ AOP์ด๋‹ค.

ํŠธ๋žœ์žญ์…˜์ด ํ•„์š”ํ•œ ํด๋ž˜์Šค๋‚˜ ๋ฉ”์„œ๋“œ์— ์ด ์–ด๋…ธํ…Œ์ด์…˜์„ ๋ถ™์ด๋ฉด,

์Šคํ”„๋ง์˜ ํŠธ๋žœ์žญ์…˜ AOP๊ฐ€ ํŠธ๋žœ์žญ์…˜ ํ”„๋ก์‹œ๋ฅผ ์ ์šฉํ•ด์ค€๋‹ค.

 

๐Ÿ“Œ ํŠธ๋žœ์žญ์…˜ ํ”„๋ก์‹œ

ํŠธ๋žœ์žญ์…˜ ์ฒ˜๋ฆฌ ๊ธฐ๋Šฅ์„ ๋Œ€์‹  ์ˆ˜ํ–‰ํ•ด์ฃผ๋Š” ๊ฐ์ฒด์ด๋‹ค.

ํŠธ๋žœ์žญ์…˜ ํ”„๋ก์‹œ๊ฐ€ ํŠธ๋žœ์žญ์…˜ ์‹œ์ž‘, ์„œ๋น„์Šค ํด๋ž˜์Šค์˜ ๋น„์ง€๋‹ˆ์Šค ํ˜ธ์ถœ, ์ปค๋ฐ‹ ๋˜๋Š” ๋กค๋ฐฑ, ์ปค๋„ฅ์…˜ ๋ฐ˜๋‚ฉ์„ ๋Œ€์‹  ํ•ด์ฃผ๊ธฐ ๋•Œ๋ฌธ์—

์„œ๋น„์Šค ํด๋ž˜์Šค์˜ ๋ฉ”์„œ๋“œ์—๋Š” ๋น„์ง€๋‹ˆ์Šค ๋กœ์ง๋งŒ ๊ตฌํ˜„ํ•ด๋‘๋ฉด ๋œ๋‹ค.

(์ด๋•Œ ์„œ๋น„์Šค ํด๋ž˜์Šค์˜ ๋ฉ”์„œ๋“œ๋Š” ํŠธ๋žœ์žญ์…˜ ํ”„๋ก์‹œ์—์„œ ํ˜ธ์ถœํ•  ์ˆ˜ ์žˆ๋„๋ก ๋ชจ๋‘ public์œผ๋กœ ๊ตฌํ˜„ํ•ด์•ผ ํ•œ๋‹ค)

 

 

728x90