Transaction

ํ”ํžˆ java์—์„œ ํŠธ๋žœ์žญ์…˜ ์‚ฌ์šฉ์‹œ try catch ๋ฌธ ์‚ฌ์ด์— commit๊ณผ Rollback์„ ์ด์šฉํ•˜์—ฌ ์ฒ˜๋ฆฌํ•œ๋‹ค.

Connection conn = null;
try {
    conn = DriverManager.getConnection(jdbcUrl, user, pw);
    conn.setAutoCommit(false);
    /*
        ...์ฟผ๋ฆฌ ์‹คํ–‰..
     */
    conn.commit();
} catch (SQLException e) {
    if(conn!=null) {
        try {
            conn.rollback();
        } catch (SQLException e1) {

        }
    }
} finally {
    if(conn!=null) {
        try {
            conn.close();
        } catch (SQLException e) {

        }
    }
}

reSpring์—์„œ๋Š” ์ด๋Ÿฌํ•œ ๋ฐ˜๋ณต์ ์ธ ์ž‘์—…์„ ๋‘ ๊ฐ€์ง€ ๋ฐฉ๋ฒ•์œผ๋กœ ํ•œ๋ฒˆ์— ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ๋‹ค.

  1. ์„ ์–ธ์— ์˜ํ•œ ํŠธ๋žœ์žญ์…˜

  2. ํ”„๋กœ๊ทธ๋žจ์— ์˜ํ•œ ํŠธ๋žœ์žญ์…˜

์„ ์–ธ์— ์˜ํ•œ ํŠธ๋žœ์žญ์…˜

์„ ์–ธ์— ์˜ํ•œ ํŠธ๋žœ์žญ์…˜์—๋Š” ๋‘๊ฐ€์ง€(1. AOP 2. annotation) ๋ฐฉ๋ฒ•์ด ์žˆ๋‹ค.

@Transactional Annotation

์šฐ์„  annotation ์‚ฌ์šฉ์„ ์œ„ํ•œ bean ์„ค์ •์„ ํ•ด์ค€๋‹ค.

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
            http://www.springframework.org/schema/beans/spring-beans.xsd
            http://www.springframework.org/schema/tx
            http://www.springframework.org/schema/tx/spring-tx.xsd">

    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"
          destroy-method="close">
        <property name="driverClass" value="com.mysql.jdbc.Driver"/>
        <property name="jdbcUrl" value=""/>
        <property name="user" value="user"/>
        <property name="password" value="pwd"/>
    </bean>

    <bean id="transactionManager"
          class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"/>
        <tx:annotation-driven transaction-manager="transactionManager"/>
    </bean>
</beans>

๋‹ค์Œ๊ณผ ๊ฐ™์ด ์„ค์ • ํ›„ ์›ํ•˜๋Š” ๋ฉ”์†Œ๋“œ ์œ„์— @Transactional ์„ ๋ถ™์—ฌ ๊ฐ„ํŽธํ•˜๊ฒŒ ํŠธ๋žœ์žญ์…˜์„ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ๋‹ค.

๋ฉ”์†Œ๋“œ ์ „์ฒด๋ฅผ ํ•˜๋‚˜์˜ ํŠธ๋žœ์žญ์…˜์œผ๋กœ ๋ฌถ์„ ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฒƒ์€@Transactional์˜ ๋‚ด๋ถ€ ๋™์ž‘์ด Proxy๋กœ ์ด๋ฃจ์–ด์ง„๋‹ค๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•œ๋‹ค.

@Transactional
public void something (int a) {
    ...
}

@Transactional ์ด ์ ์šฉ๋œ ๊ฒฝ์šฐ ํŠธ๋žœ์žญ์…˜ ๊ธฐ๋Šฅ์ด ์ ์šฉ๋œ ํ”„๋ก์‹œ ๊ฐ์ฒด๊ฐ€ ์ƒ์„ฑ๋œ๋‹ค.

์ด ํ”„๋ก์‹œ ๊ฐ์ฒด๋Š” @Transactional์ด ํฌํ•จ๋œ ๋ฉ”์†Œ๋“œ๊ฐ€ ํ˜ธ์ถœ๋˜๋ฉด, PlatformTransactionManager๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํŠธ๋žœ์žญ์…˜์„ ์‹œ์ž‘ํ•˜๊ณ , ๊ฒฐ๊ณผ์˜ ์ •์ƒ ์—ฌ๋ถ€์— ๋”ฐ๋ผ Commit ๋˜๋Š” Rollback ํ•œ๋‹ค.

@Transactional ์–ด๋…ธํ…Œ์ด์…˜์— ์—ฌ๋Ÿฌ๊ฐ€์ง€ ์†์„ฑ์„ ์ง€์ •ํ•  ์ˆ˜ ์žˆ๋‹ค.

@Transactional(isolation = Isolation.READ_COMMITTED, propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
public int method(int i) throws Exception {
    return sqlMapClient.delete("");
}

isolation

๊ฒฉ๋ฆฌ์ˆ˜์ค€(ํŠธ๋žœ์žญ์…˜์—์„œ ์ผ๊ด€์„ฑ์ด ์—†๋Š” ๋ฐ์ดํ„ฐ๋ฅผ ํ—ˆ์šฉํ•˜๋„๋ก ํ•˜๋Š” ์ˆ˜์ค€)์„ ๋งํ•˜๋Š”๋ฐ ์˜ต์…˜์€ ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

level

์˜ต์…˜

์„ค๋ช…

level 0

READ_UNCOMMITTED

ํŠธ๋žœ์žญ์…˜์— ์ฒ˜๋ฆฌ์ค‘์ธ or ์•„์ง commit(ํ™•์ •)๋˜์ง€ ์•Š์€ ๋ฐ์ดํ„ฐ๋ฅผ ๋‹ค๋ฅธ ํŠธ๋žœ์žญ์…˜์ด ์ฝ๋Š” ๊ฒƒ์„ ํ—ˆ์šฉํ•œ๋‹ค. ex) ํ•œ ์‚ฌ์šฉ์ž๊ฐ€ A๋ผ๋Š” ๋ฐ์ดํ„ฐ๋ฅผ B๋ผ๋Š” ๋ฐ์ดํ„ฐ๋กœ ๋ณ€๊ฒฝํ•˜๋Š” ๋™์•ˆ ๋‹ค๋ฅธ ์‚ฌ์šฉ์ž๋Š” ์•„์ง ์™„๋ฃŒ๋˜์ง€์•Š์€(Uncommitted or Dirty) ๋ฐ์ดํ„ฐ B'๋ฅผ ์ฝ์„ ์ˆ˜ ์žˆ๋‹ค.

level 1

READ_COMMITTED

Dirty Read๋ฅผ ๋ฐฉ์ง€ํ•œ๋‹ค. ์ฆ‰, ํŠธ๋žœ์žญ์…˜์ด commit๋˜์–ด ํ™•์ •๋œ ๋ฐ์ดํ„ฐ๋งŒ์„ ์ฝ๋Š” ๊ฒƒ์„ ํ—ˆ์šฉํ•œ๋‹ค. ex) ํ•œ ์‚ฌ์šฉ์ž๊ฐ€ A๋ผ๋Š” ๋ฐ์ดํ„ฐ๋ฅผ B๋ผ๋Š” ๋ฐ์ดํ„ฐ๋กœ ๋ณ€๊ฒฝํ•˜๋Š” ๋™์•ˆ ๋‹ค๋ฅธ ์‚ฌ์šฉ์ž๋Š” ํ•ด๋‹น ๋ฐ์ดํ„ฐ์— ์ ‘๊ทผํ•  ์ˆ˜ ์—†๋‹ค.

level 2

REPEATABLE_READ

ํŠธ๋žœ์žญ์…˜์ด ์™„๋ฃŒ๋  ๋•Œ๊นŒ์ง€ SELECT๋ฌธ์ด ์‚ฌ์šฉํ•˜๋Š” ๋ชจ๋“  ๋ฐ์ดํ„ฐ์— shared lock์ด ๊ฑธ๋ฆฐ๋‹ค. ๋‹ค๋ฅธ ์‚ฌ์šฉ์ž๋Š” ๊ทธ ์˜์—ญ์— ํ•ด๋‹น๋˜๋Š” ๋ฐ์ดํ„ฐ์— ๋Œ€ํ•œ ์ˆ˜์ •์ด ๋ถˆ๊ฐ€๋Šฅํ•˜๋‹ค. ์„ ํ–‰ ํŠธ๋žœ์žญ์…˜์ด ์ฝ์€ ๋ฐ์ดํ„ฐ๋Š” ํŠธ๋žœ์žญ์…˜์ด ์ข…๋ฃŒ๋  ๋•Œ๊นŒ์ง€ ํ›„ํ–‰ ํŠธ๋žœ์žญ์…˜์ด ๊ฐฑ์‹ ํ•˜๊ฑฐ๋‚˜ ์‚ญ์ œํ•˜๋Š” ๊ฒƒ์„ ๋ถˆํ—ˆํ•จ์œผ๋กœ์จ ๊ฐ™์€ ๋ฐ์ดํ„ฐ๋ฅผ ๋‘ ๋ฒˆ ์ฟผ๋ฆฌํ–ˆ์„ ๋•Œ ์ผ๊ด€์„ฑ ์žˆ๋Š” ๊ฒฐ๊ณผ๋ฅผ ๋ฆฌํ„ดํ•จ

level 3

SERIALIZABLE

์™„๋ฒฝํ•œ ์ฝ๊ธฐ ์ผ๊ด€์„ฑ ๋ชจ๋“œ๋ฅผ ์ œ๊ณตํ•œ๋‹ค. ๋ฐ์ดํ„ฐ์˜ ์ผ๊ด€์„ฑ ๋ฐ ๋™์‹œ์„ฑ์„ ์œ„ํ•ด MVCC๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š”๋‹ค. ํŠธ๋žœ์žญ์…˜์ด ์™„๋ฃŒ๋  ๋•Œ๊นŒ์ง€ SELECT ๋ฌธ์žฅ์ด ์‚ฌ์šฉํ•˜๋Š” ๋ชจ๋“  ๋ฐ์ดํ„ฐ์— shared lock์ด ๊ฑธ๋ฆฌ๋ฏ€๋กœ ๋‹ค๋ฅธ ์‚ฌ์šฉ์ž๋Š” ๊ทธ ์˜์—ญ์— ํ•ด๋‹น๋˜๋Š” ๋ฐ์ดํ„ฐ์— ๋Œ€ํ•œ ์ˆ˜์ • ๋ฐ ์ž…๋ ฅ์ด ๋ถˆ๊ฐ€๋Šฅํ•˜๋‹ค.

Dirty read

์œ„์™€ ๊ฐ™์ด ๋‹ค๋ฅธ ํŠธ๋žœ์žญ์…˜์—์„œ ์ฒ˜๋ฆฌํ•˜๋Š” ์ž‘์—…์ด ์™„๋ฃŒ๋˜์ง€ ์•Š์•˜๋Š”๋ฐ๋„ ๋‹ค๋ฅธ ํŠธ๋žœ์žญ์…˜์—์„œ ๋ณผ ์ˆ˜ ์žˆ๋Š” ํ˜„์ƒ์„ dirty read ๋ผ๊ณ  ํ•˜๋ฉฐ, READ UNCOMMITTED ๊ฒฉ๋ฆฌ์ˆ˜์ค€์—์„œ๋งŒ ์ผ์–ด๋‚˜๋Š” ํ˜„์ƒ

MVVC(Multi Version Concurrency Control)

MVCC๋Š” ๋‹ค์ค‘ ์‚ฌ์šฉ์ž ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์„ฑ๋Šฅ์„ ์œ„ํ•œ ๊ธฐ์ˆ ๋กœ ๋ฐ์ดํ„ฐ ์กฐํšŒ ์‹œ LOCK์„ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ณ  ๋ฐ์ดํ„ฐ์˜ ๋ฒ„์ „์„ ๊ด€๋ฆฌํ•ด ๋ฐ์ดํ„ฐ์˜ ์ผ๊ด€์„ฑ ๋ฐ ๋™์‹œ์„ฑ์„ ๋†’์ด๋Š” ๊ธฐ์ˆ 

propagation

ํŠธ๋žœ์žญ์…˜ ๋™์ž‘ ๋„์ค‘์— ๋‹ค๋ฅธ ํŠธ๋žœ์žญ์…˜์„ ์‹คํ–‰ํ•ด์•ผํ•˜๋Š” ์ƒํ™ฉ์ด ์ž์ฃผ ๋ฐœ์ƒํ•˜๊ฒŒ ๋˜๋Š”๋ฐ, ํ˜ธ์ถœ๋˜๋Š” ํŠธ๋žœ์žญ์…˜์˜ ์ž…์žฅ์—์„œ๋Š” ํ˜ธ์ถœํ•œ ํŠธ๋žœ์žญ์…˜์„ ๊ทธ๋Œ€๋กœ ์‚ฌ์šฉํ•  ์ˆ˜๋„ ์žˆ๊ณ , ์ƒˆ๋กœ์šด ํŠธ๋žœ์žญ์…˜์„ ์ƒ์„ฑํ•  ์ˆ˜๋„ ์žˆ๋‹ค.

  • ํ˜ธ์ถœํ•œ ํŠธ๋žœ์žญ์…˜์„ ๊ทธ๋Œ€๋กœ ์‚ฌ์šฉํ•œ ๊ฒฝ์šฐ ์ค‘๊ฐ„์— ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด ๋ชจ๋“  ํŠธ๋žœ์žญ์…˜์ด ๋กค๋ฐฑ์ด ๋œ๋‹ค.

  • ์ƒˆ๋กœ์šด ํŠธ๋žœ์žญ์…˜์„ ์ƒ์„ฑํ•œ ๊ฒฝ์šฐ ์ค‘๊ฐ„์— ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•œ ํŠธ๋žœ์žญ์…˜์ด ๋กค๋ฐฑ ๋  ๊ฒƒ์ด๋‹ค.

์ด๋Ÿฌํ•œ ํŠธ๋žœ์žญ์…˜ ๊ด€๋ จ ์„ค์ •์€ @Transactional์˜ propagation ์†์„ฑ์„ ํ†ตํ•ด ์ง€์ •ํ•  ์ˆ˜ ์žˆ๋‹ค.

@Transactional(propagation = Propagation.REQUIRES_NEW)
public void something (int a) {
    โ€ฆ
}

propagation ์†์„ฑ

์„ค๋ช…

REQUIRED

๋ถ€๋ชจ ํŠธ๋žœ์žญ์…˜ ๋‚ด์—์„œ ์‹คํ–‰ํ•˜๋ฉฐ ๋ถ€๋ชจ ํŠธ๋žœ์žญ์…˜์ด ์—†์„ ๊ฒฝ์šฐ ์ƒˆ๋กœ์šด ํŠธ๋žœ์žญ์…˜์„ ์ƒ์„ฑ

REQUIRES_NEW

๋ถ€๋ชจ ํŠธ๋žœ์žญ์…˜์„ ๋ฌด์‹œํ•˜๊ณ  ๋ฌด์กฐ๊ฑด ์ƒˆ๋กœ์šด ํŠธ๋žœ์žญ์…˜์ด ์ƒ์„ฑ

MANDATORY

๋ถ€๋ชจ ํŠธ๋žœ์žญ์…˜ ๋‚ด์—์„œ ์‹คํ–‰๋˜๋ฉฐ ๋ถ€๋ชจ ํŠธ๋žœ์žญ์…˜์ด ์—†์„ ๊ฒฝ์šฐ ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒ

SUPPORTS

๋ถ€๋ชจ ํŠธ๋žœ์žญ์…˜ ๋‚ด์—์„œ ์‹คํ–‰ํ•˜๋ฉฐ ๋ถ€๋ชจ ํŠธ๋žœ์žญ์…˜์ด ์—†์„ ๊ฒฝ์šฐ nontransactionally๋กœ ์‹คํ–‰

NOT_SUPPORTED

nontransactionally๋กœ ์‹คํ–‰ํ•˜๋ฉฐ ๋ถ€๋ชจ ํŠธ๋žœ์žญ์…˜ ๋‚ด์—์„œ ์‹คํ–‰๋  ๊ฒฝ์šฐ ์ผ์‹œ ์ •์ง€

NEVER

nontransactionally๋กœ ์‹คํ–‰๋˜๋ฉฐ ๋ถ€๋ชจ ํŠธ๋žœ์žญ์…˜์ด ์กด์žฌํ•œ๋‹ค๋ฉด ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒ

NESTED

ํ•ด๋‹น ๋ฉ”์„œ๋“œ๊ฐ€ ๋ถ€๋ชจ ํŠธ๋žœ์žญ์…˜์—์„œ ์ง„ํ–‰๋  ๊ฒฝ์šฐ ๋ณ„๊ฐœ๋กœ ์ปค๋ฐ‹๋˜๊ฑฐ๋‚˜ ๋กค๋ฐฑ๋  ์ˆ˜ ์žˆ๋‹ค. ๋‘˜๋Ÿฌ์‹ผ ํŠธ๋žœ์žญ์…˜์ด ์—†์„ ๊ฒฝ์šฐ REQUIRED์™€ ๋™์ผํ•˜๊ฒŒ ์ž‘๋™

rollback-for

ํŠน์ • ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒํ–ˆ์„ ๊ฒฝ์šฐ์— ๋กค๋ฐฑ๋˜๋„๋ก ์„ค์ •ํ•œ๋‹ค. ์„ค์ •ํ•˜์ง€ ์•Š์„ ๊ฒฝ์šฐ ์˜ค๋กœ์ง€ RuntimeException์„ ์ƒ์†๋ฐ›์€ ์˜ˆ์™ธ์—๋งŒ ๋กค๋ฐฑ์ฒ˜๋ฆฌ๋ฅผ ํ•ด์ค€๋‹ค.

no-rollback-for

ํŠน์ • ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒํ•˜๋”๋ผ๋„ ๋กค๋ฐฑ๋˜์ง€ ์•Š๋„๋ก ์„ค์ •ํ•œ๋‹ค.

์ฐธ์กฐ

Last updated