BackEnd/SpringBoot

Spring Transaction ์— ๋Œ€ํ•œ ์ดํ•ด

hyunki.Dev 2023. 9. 20. 13:57

๐Ÿ“Œ ๋“ค์–ด๊ฐ€๋ฉฐ 

์ฝ”๋“œ๋ฆฌ๋ทฐ๋ฅผ ์ง„ํ–‰ํ•˜๋‹ค ๋ณด๋ฉด ํ•ญ์ƒ ๋‚˜์˜ค๋Š” ์–˜๊ธฐ ์ค‘ ํ•˜๋‚˜๊ฐ€ ๋ฐ”๋กœ 'ํŠธ๋žœ์žญ์…˜ ๊ด€๋ฆฌ๋ฅผ ์–ด๋–ป๊ฒŒ ํ• ๊ฒƒ์ธ๊ฐ€' ์— ๋Œ€ํ•œ ๋‚ด์šฉ์ž…๋‹ˆ๋‹ค.

๊ทธ๋งŒํผ Exception์ด ๋ฐœ์ƒํ–ˆ์„ ๋•Œ ์–ด๋–ป๊ฒŒ ํ•  ๊ฒƒ์ธ๊ฐ€์— ๋Œ€ํ•œ ๋‚ด์šฉ์ด ์ค‘์š”ํ•œ ๋งŒํผ ์ด์— ๋Œ€ํ•œ ๋Œ€์ฒ˜ ์ค‘ ํ•˜๋‚˜์ธ Transaction์— ๋Œ€ํ•ด ์ •๋ฆฌํ•ด ๋ณด๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค. 


๐Ÿ“Œ Transaction ์˜ ์ •์˜

 ํŠธ๋žœ์žญ์…˜์€ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์˜ ์ƒํƒœ๋ฅผ ๋ณ€๊ฒฝํ•˜๋Š” ์ž‘์—… ๋˜๋Š” ํ•œ๋ฒˆ์— ์ˆ˜ํ–‰๋˜์–ด์•ผ ํ•˜๋Š” ์—ฐ์‚ฐ๋“ค์„ ๋œปํ•ฉ๋‹ˆ๋‹ค.

์ฆ‰, ๋ณ‘ํ–‰ ์ œ์–ด ์‹œ ์ฒ˜๋ฆฌ๋˜๋Š” ์ž‘์—…์˜ ๋…ผ๋ฆฌ์  ๋‹จ์œ„์ž…๋‹ˆ๋‹ค.

 

Transaction์€ ํ•˜๋‚˜์˜ ํ๋ฆ„์œผ๋กœ ํ•˜๋‚˜์˜ ์‹คํ–‰์ด ์„ฑ๊ณตํ•˜๊ฑฐ๋‚˜ ์‹คํŒจํ•˜๋ฉด ๋ชจ๋“  ์—ฐ์‚ฐ๋“ค์„ ๋™์ผํ•˜๊ฒŒ ์ฒ˜๋ฆฌํ•ฉ๋‹ˆ๋‹ค.

A, B, C์˜ ์—ฐ์‚ฐ์„ ํ•œ ๋ฌถ์Œ์ด๋ผ๊ณ  ํ•  ๋•Œ A๋Š” ์ •์ƒ ์ž‘๋™ ๋์ง€๋งŒ,

B๊ฐ€ ์‹คํŒจํ•œ๋‹ค๋ฉด A์˜ ์ž‘์—… ์ด๋ ฅ๋„ ์ด์ „์œผ๋กœ ๋Œ๋ฆฝ๋‹ˆ๋‹ค.

 

๋ชจ๋“  ์ž‘์—…์ด ์„ฑ๊ณตํ•œ๋‹ค๋ฉด ์™„๋ฃŒ ์ž‘์—… ์ƒํƒœ๋ฅผ ๋ชจ๋‘ ๋ฐ˜์˜ํ•˜๊ณ , ์ด๊ฒƒ์„ Commit์ด๋ผ๊ณ  ํ•ฉ๋‹ˆ๋‹ค.

๋ฐ˜๋ฉด, ํ•˜๋‚˜๋ผ๋„ ์‹คํŒจํ•˜๊ฒŒ ๋œ๋‹ค๋ฉด ๋ชจ๋“  ์‚ฌํ•ญ์„ ํ๊ธฐํ•˜๊ณ , ์ด๊ฒƒ์„ Rollback์ด๋ผ๊ณ  ํ•ฉ๋‹ˆ๋‹ค.


๐Ÿ“Œ Transaction ์˜ 4๊ฐ€์ง€ ์„ฑ์งˆ

ํŠธ๋žœ์žญ์…˜์€ 4๊ฐ€์ง€์˜ ์„ฑ์งˆ์„ ๊ฐ€์ง€๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

 

์ด๋ฅผ ACID ๋ผ๊ณ  ํ•˜๋Š”๋ฐ ํ•ด๋‹น ์„ฑ์งˆ์€ ์•„๋ž˜์™€ ๊ฐ™์Šต๋‹ˆ๋‹ค.

 

Atomicity ์›์ž์„ฑ

: ํ•œ ํŠธ๋žœ์žญ์…˜ ๋‚ด์˜ ์‹คํ–‰ ์ž‘์—…์€ ํ•˜๋‚˜์˜ ๋‹จ์œ„๋กœ ์ฒ˜๋ฆฌํ•œ๋‹ค. / ๋ชจ๋‘ ์„ฑ๊ณต ๋˜๋Š” ๋ชจ๋‘ ์‹คํŒจ

Consistency ์ผ๊ด€์„ฑ

: ํŠธ๋žœ์žญ์…˜์€ ์ผ๊ด€์„ฑ ์žˆ๋Š” ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์˜ ์ƒํƒœ๋ฅผ ์œ ์ง€ํ•œ๋‹ค.

โžก๏ธ ํ•˜๋‚˜์˜ ๋™์ž‘์ด ์ •์ƒ์ ์ธ ํ๋ฆ„์„ ์ผ๊ด€๋˜๊ฒŒ ์œ ์ง€ํ•˜์—ฌ์•ผ ํ•œ๋‹ค๋Š” ์›์น™์ž…๋‹ˆ๋‹ค.

Isolation ๋…๋ฆฝ์„ฑ

: ๋™์‹œ์— ์‹คํ–‰๋˜๋Š” ํŠธ๋žœ์žญ์…˜๋“ค์ด ์„œ๋กœ ์˜ํ–ฅ์„ ๋ฏธ์น˜์ง€ ์•Š๋„๋ก ๋…๋ฆฝ๋˜์–ด์•ผ ํ•œ๋‹ค.

โžก๏ธ ๊ฒฉ๋ฆฌ์„ฑ ์ด๋ผ๊ณ ๋„ ํ•˜๋Š” ์ด ์„ฑ์งˆ์€ ํ•˜๋‚˜์˜ ๋™์ž‘ ์ค‘ ๋‹ค๋ฅธ ํŠธ๋žœ์žญ์…˜์ด ๊ฐœ์ž…ํ•˜์—ฌ ๋ฐ์ดํ„ฐ ๋ณ€๊ฒฝ์ด ์ผ์–ด๋‚˜์„œ๋Š”

์•ˆ๋œ๋‹ค๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค.  (ํ•œ ๋™์ž‘์ด ๋…๋ฆฝ์ ์œผ๋กœ ์ฒ˜๋ฆฌ)

Durability ์˜์†์„ฑ

: ํŠธ๋žœ์žญ์…˜์ด ์„ฑ๊ณต์ ์œผ๋กœ ๋งˆ์น˜๋ฉด ๊ฒฐ๊ณผ๊ฐ€ ํ•ญ์ƒ ์ €์žฅ๋˜์–ด์•ผ ํ•œ๋‹ค.

โžก๏ธ ํŠธ๋žœ์žญ์…˜์˜ ๋™์ž‘์ด ์„ฑ๊ณต ํ›„ Commit ๋˜๊ฒŒ ๋œ๋‹ค๋ฉด ์ด๋Š” ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ์˜์›ํžˆ ๋ฐ˜์˜๋˜์–ด์•ผ ํ•œ๋‹ค๋Š” ์›์น™์ž…๋‹ˆ๋‹ค.

 


๐Ÿ“Œ TransactionManager ์˜ ์ข…๋ฅ˜

โœ”๏ธ DataSourceTransactionManager

: JDBC ๋ฐ MyBatis ๋“ฑ์˜ JDBC ๊ธฐ๋ฐ˜ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋กœ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ์ ‘๊ทผํ•˜๋Š” ๊ฒฝ์šฐ์— ์ด์šฉํ•ฉ๋‹ˆ๋‹ค.

์ด ํŠธ๋žœ์žญ์…˜ ๋งค๋‹ˆ์ €๋ฅผ ์‚ฌ์šฉํ•˜๋ ค๋ฉด ํŠธ๋žœ์žญ์…˜์„ ์ ์šฉํ•  DataSource๊ฐ€ ์Šคํ”„๋ง์˜ ๋นˆ์œผ๋กœ ๋“ฑ๋ก๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. 

ํ˜„์žฌ ์ œ๊ฐ€ ๋‹ค๋‹ˆ๊ณ  ์žˆ๋Š” ํšŒ์‚ฌ ๋Œ€๋ถ€๋ถ„์˜ ์„œ๋ธŒ ๋„๋ฉ”์ธ์ด ์ด ๋ฐฉ์‹์˜ TransactionManager๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

 

โœ”๏ธ HibernateTransactionManager

: ํ•˜์ด๋ฒ„๋„ค์ดํŠธ๋ฅผ ์ด์šฉํ•ด ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ์ ‘๊ทผํ•˜๋Š” ๊ฒฝ์šฐ์— ์ด์šฉํ•ฉ๋‹ˆ๋‹ค.

 

โœ”๏ธ JpaTransactionManager

: JPA๋กœ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ์ ‘๊ทผํ•˜๋Š” ๊ฒฝ์šฐ์— ์ด์šฉํ•ฉ๋‹ˆ๋‹ค.

JpaTransactionManager๋Š” LocalContainerEntityManagerFactoryBeanํƒ€์ž…์˜ ๋นˆ์„ ๋“ฑ๋กํ•ด์ค˜์•ผํ•ฉ๋‹ˆ๋‹ค.


โœ”๏ธ JtaTransactionManager

: ํ•˜๋‚˜ ์ด์ƒ์˜ DB ๋‚˜ ๊ธ€๋กœ๋ฒŒ ํŠธ๋žœ์žญ์…˜์„ ์ ์šฉํ•˜๋ ค๋ฉด JTA ์ด์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

JTA๋Š” ์—ฌ๋Ÿฌ ๊ฐœ์˜ ํŠธ๋žœ์žญ์…˜ ๋ฆฌ์†Œ์Šค(DB, JMS ๋“ฑ)์— ๋Œ€ํ•œ ์ž‘์—…์„ ํ•˜๋‚˜์˜ ํŠธ๋žœ์žญ์…˜์œผ๋กœ ๋ฌถ์„ ์ˆ˜ ์žˆ๊ณ ,

์—ฌ๋Ÿฌ ๋Œ€์˜ ์„œ๋ฒ„์— ๋ถ„์‚ฐ๋˜์–ด ์ง„ํ–‰๋˜๋Š” ์ž‘์—…์„ ํŠธ๋žœ์žญ์…˜์œผ๋กœ ์—ฐ๊ฒฐํ•ด์ฃผ๊ธฐ๋„ ํ•ฉ๋‹ˆ๋‹ค.

 

 

DB๊ฐ€ ํ•˜๋‚˜๋ผ๋ฉด ํŠธ๋žœ์žญ์…˜ ๋งค๋‹ˆ์ € ๋˜ํ•œ ํ•˜๋‚˜๋งŒ ๋“ฑ๋ก๋˜์–ด์•ผ ํ•˜๊ณ ,
์—ฌ๋Ÿฌ๊ฐœ๋ผ๋„ JTA๋ฅผ ์ด์šฉํ•œ ๊ธ€๋กœ๋ฒŒ ํŠธ๋ž™์žญ์…˜์„ ์ ์šฉํ• ๊ฒƒ์ด๋ผ๋ฉด JtaTransactionManager ํ•˜๋‚˜๋งŒ ๋“ฑ๋ก๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

๋…๋ฆฝ๋œ ๋‘ ๊ฐœ ์ด์ƒ์˜ DB๋ผ๋ฉด DataSource๋„ ๋‘ ๊ฐœ๊ฐ€ ๋“ฑ๋ก๋˜๋ฏ€๋กœ,

DB ์ˆ˜์— ๋”ฐ๋ฅธ ํŠธ๋žœ์žญ์…˜ ๋งค๋‹ˆ์ €๋ฅผ ๋“ฑ๋กํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

ํ•œ ๊ฐœ์˜ ์„œ๋ธŒ ๋„๋ฉ”์ธ์—์„œ ๊ฐ๊ธฐ ๋‹ค๋ฅธ MySQL, Oracle ๋‘ ๊ฐ€์ง€ DB์— ์ ‘๊ทผ์ด ํ•„์š”ํ•  ๊ฒฝ์šฐ

์ด์ค‘ Datasource๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด์„œ ํŠธ๋žœ์žญ์…˜ ๋งค๋‹ˆ์ € ๋˜ํ•œ ๋‘ ๊ฐœ๋ฅผ ๋“ฑ๋กํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

 


๐Ÿ“Œ @Transactional

Spring์—์„œ๋Š” ํŠธ๋žœ์žญ์…˜์ด ์ ์šฉ๋  ํƒ€๊นƒ ์ธํ„ฐํŽ˜์ด์Šค๋‚˜ ํด๋ž˜์Šค, ๋ฉ”์†Œ๋“œ ๋“ฑ์— @Transactional ์–ด๋…ธํ…Œ์ด์…˜์„ ๋ถ€์—ฌํ•˜์—ฌ,

ํŠธ๋žœ์žญ์…˜ ๋Œ€์ƒ์œผ๋กœ ์ง€์ •ํ•˜๊ณ  ํŠธ๋žœ์žญ์…˜์˜ ์†์„ฑ์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

 

์ฆ‰, ํŠธ๋žœ์žญ์…˜์„ ์ ์šฉํ•˜๊ณ ์ž ํ•˜๋Š” ๊ณณ์— @Transactional ์„ ๋ถ™์ด๋ฉด ์ ์šฉ๋œ๋‹ค๋Š” ์˜๋ฏธ์ž…๋‹ˆ๋‹ค.

@Transactional์˜ ์ •์˜๋ฅผ ๋ณด๋ฉด ์•„๋ž˜์™€ ๊ฐ™์Šต๋‹ˆ๋‹ค.

 

@Target(value={TYPE,METHOD})
 @Retention(value=RUNTIME)
 @Inherited
 @Documented
public @interface Transactional {}

 

Transactional Annotation์€ Target์ด TYPE๊ณผ METHOD ์ž…๋‹ˆ๋‹ค.

์ฆ‰, Class, interface, enum (TYPE) ์ด๋‚˜, Method (METHOD) ์— ์ ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ์˜๋ฏธ์ž…๋‹ˆ๋‹ค.

 

๋‘ ๊ฐœ์˜ Target์— ๋™์‹œ์— ๋ถ™์ผ ์ˆ˜๋„ ์žˆ๋Š”๋ฐ์š”, ๊ทธ ๋•Œ์—๋Š” ๋ฉ”์†Œ๋“œ์— ๋ถ™์€ ์• ๋…ธํ…Œ์ด์…˜์ด ์šฐ์„ ์‹œ๋˜์–ด ์ ์šฉ๋ฉ๋‹ˆ๋‹ค.

์•„๋ž˜์˜ ์˜ˆ์‹œ๋ฅผ ๋ณด๋ฉด, readMember์—๋Š” readOnly ์†์„ฑ์˜ default๊ฐ’์ธ false๊ฐ€ ๋ฌด์‹œ๋˜๊ณ 

๋ฉ”์†Œ๋“œ ๋ฒ”์œ„์˜ ์„ค์ •์ด ์šฐ์„ ์‹œ ๋˜์–ด readOnly๊ฐ€ true๋กœ ์ ์šฉ๋ฉ๋‹ˆ๋‹ค.

 

@Transactional
public interface MemberAnnotService {
    @Transactional(readOnly=true)
    void readMember(long memberId);

    void addMember(List<Member> members);
}

 


๐Ÿ“Œ  Transaction Properties

์„ ์–ธ์  ํŠธ๋žœ์žญ์…˜์€ 6๊ฐ€์ง€์˜ ์†์„ฑ์„ ๊ฐ€์ง€๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ

์†์„ฑ์„ ์ ๋‹นํžˆ ํ™œ์šฉํ•˜์—ฌ ๋กœ์ง์ƒ ํ•„์š”์— ์˜ํ•ด ์ ์ •ํžˆ ์กฐ์ •ํ•  ์ˆ˜ ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

 

์ผ๋ฐ˜์ ์œผ๋กœ ํŠธ๋žœ์žญ์…˜์˜ ๊ฒฝ๊ณ„๋ฅผ ์„ค์ •ํ•  ๋•Œ๋Š”

Propagation, Isolation, Timeout, ReadOnly ์˜ ๋„ค ๊ฐ€์ง€ ํŠธ๋žœ์žญ์…˜ ์†์„ฑ์œผ๋กœ ํŠธ๋žœ์žญ์…˜๋งˆ๋‹ค ์ง€์ •ํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ

 

์„ ์–ธ์  ํŠธ๋žœ์žญ์…˜์—์„œ๋Š” ๋กค๋ฐฑ๊ณผ ์ปค๋ฐ‹์˜ ๊ธฐ์ค€์„ ๋ณ€๊ฒฝํ•˜๊ธฐ ์œ„ํ•ด

RollbackFor,  noRollbackFor ์ด๋ผ๋Š” ๋‘ ๊ฐ€์ง€ ์ถ”๊ฐ€ ์†์„ฑ์„ ์ง€์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

 

โœ”๏ธ Propagation

: ํŠธ๋žœ์žญ์…˜ ์ „ํŒŒ

 

ํŠธ๋žœ์žญ์…˜์„ ์‹œ์ž‘ํ•˜๊ณ , ํ˜น์€ ํŠธ๋žœ์žญ์…˜์„ ์ˆ˜ํ–‰ํ•˜๋‹ค๊ฐ€ ๋‹ค๋ฅธ ํŠธ๋žœ์žญ์…˜์„ ๋งˆ์ฃผํ•˜๋ฉด ์–ด๋–ป๊ฒŒ ํ• ๊นŒ์š”?

๊ทธ ์ฒ˜๋ฆฌ ๋ฐฉ์‹์— ๋Œ€ํ•œ ์„ค์ •์ž…๋‹ˆ๋‹ค.

 

์ฆ‰, ํŠธ๋žœ์žญ์…˜์„ ์‹œ์ž‘ํ•˜๊ฑฐ๋‚˜ ๊ธฐ์กด ํŠธ๋žœ์žญ์…˜์— ์ฐธ์—ฌํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ๊ฒฐ์ •ํ•˜๋Š” ์†์„ฑ์ž…๋‹ˆ๋‹ค.

์„ ์–ธ์  ํŠธ๋žœ์žญ์…˜ ๋ฐฉ์‹์˜ ์žฅ์ ์€, ์—ฌ๋Ÿฌ ํŠธ๋žœ์žญ์…˜ ์ ์šฉ ๋ฒ”์œ„๋ฅผ ๋ฌถ์–ด์„œ ์ปค๋‹ค๋ž€ ํŠธ๋žœ์žญ์…˜ ๊ฒฝ๊ณ„๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ง€์ •ํ•  ์ˆ˜ ์žˆ๋Š” ์†์„ฑ์€ ์•„๋ž˜์™€ ๊ฐ™์Šต๋‹ˆ๋‹ค.

 

โœ… REQUIRED

: Default. ์ด๋ฏธ ์‹œ์ž‘๋œ ํŠธ๋žœ์žญ์…˜์ด ์žˆ์œผ๋ฉด ์ฐธ์—ฌํ•˜๊ณ , ์—†์œผ๋ฉด ์ƒˆ๋กœ ์ƒ์„ฑํ•ด ์‹œ์ž‘ํ•ฉ๋‹ˆ๋‹ค.

๋Œ€๊ฐœ ์ด ์†์„ฑ์ด๋ฉด ์ถฉ๋ถ„ํ•˜๋ฉฐ, ์ž์—ฐ์Šค๋Ÿฝ๊ณ  ๊ฐ„๋‹จํ•œ ํŠธ๋žœ์žญ์…˜ ์ „ํŒŒ ๋ฐฉ์‹์ด์ง€๋งŒ ์‚ฌ์šฉํ•ด๋ณด๋ฉด ๋งค์šฐ ๊ฐ•๋ ฅํ•˜๊ณ  ์œ ์šฉํ•ฉ๋‹ˆ๋‹ค.

ํ•˜๋‚˜์˜ ํŠธ๋žœ์žญ์…˜์ด ์‹œ์ž‘๋œ ํ›„ ๋‹ค๋ฅธ ํŠธ๋žœ์žญ์…˜ ๊ฒฝ๊ณ„๊ฐ€ ์„ค์ •๋œ ๋ฉ”์†Œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด ์ž์—ฐ์Šค๋Ÿฝ๊ฒŒ ๊ฐ™์€ ํŠธ๋žœ์žญ์…˜์œผ๋กœ ๋ฌถ์ž…๋‹ˆ๋‹ค.

 

โœ… SUPPORT

: ์ด๋ฏธ ์‹œ์ž‘๋œ ํŠธ๋žœ์žญ์…˜์ด ์žˆ์œผ๋ฉด ์ฐธ์—ฌํ•˜๊ณ , ์—†์œผ๋ฉด ํŠธ๋žœ์žญ์…˜ ์—†์ด ์ง„ํ–‰ํ•ฉ๋‹ˆ๋‹ค.

 

โœ… MANDATORY

: ์ด๋ฏธ ์‹œ์ž‘๋œ ํŠธ๋žœ์žญ์…˜์ด ์žˆ์œผ๋ฉด ์ฐธ์—ฌํ•˜๊ณ , ์—†์œผ๋ฉด ์˜ˆ์™ธ๋ฅผ ๋ฐœ์ƒ ์‹œํ‚ต๋‹ˆ๋‹ค.

 

โœ… REQUIRES_NEW

: ํ•ญ์ƒ ์ƒˆ๋กœ์šด ํŠธ๋žœ์žญ์…˜์„ ์‹œ์ž‘ํ•˜๊ณ , ์ด๋ฏธ ์‹œ์ž‘๋œ ํŠธ๋žœ์žญ์…˜์ด ์žˆ์œผ๋ฉด ๋ณด๋ฅ˜ํ•˜๊ณ  ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.

 

โœ… NOT_SUPPORTED

: ํŠธ๋žœ์žญ์…˜์„ ์ „ํ˜€ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ณ , ์ด๋ฏธ ์‹œ์ž‘๋œ ํŠธ๋žœ์žญ์…˜์ด ์žˆ์œผ๋ฉด ๋ณด๋ฅ˜ํ•ฉ๋‹ˆ๋‹ค.

 

โœ… NEVER

: ํŠธ๋žœ์žญ์…˜์„ ๊ฐ•์ œ๋กœ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ณ , ์ด๋ฏธ ์‹œ์ž‘๋œ ํŠธ๋žœ์žญ์…˜์ด ์žˆ์œผ๋ฉด ์˜ˆ์™ธ๋ฅผ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.

ํŠธ๋žœ์žญ์…˜์„ ์ง€์›ํ•˜์ง€ ์•Š๋Š” ์„ค์ •์ž…๋‹ˆ๋‹ค.

NOT_SUPPORTED์™€ ๋น„์Šทํ•˜์ง€๋งŒ, ์˜ˆ์™ธ๋ฅผ ๋ฐœ์ƒ์‹œํ‚ค๋Š” ์ ์ด ๋‹ค๋ฆ…๋‹ˆ๋‹ค.

 

โœ… NESTED

: ์ด๋ฏธ ์‹œ์ž‘๋œ ํŠธ๋žœ์žญ์…˜์ด ์žˆ์œผ๋ฉด ์ค‘์ฒฉ ํŠธ๋žœ์žญ์…˜์„ ์‹œ์ž‘ํ•˜๊ณ , ๋ถ€๋ชจ ํŠธ๋žœ์žญ์…˜์— ์˜ํ–ฅ์„ ์ฃผ์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

 

์ค‘์ฒฉ ํŠธ๋žœ์žญ์…˜์ด๋ผ ํŠธ๋žœ์žญ์…˜ ์•ˆ์— ํŠธ๋žœ์žญ์…˜์„ ๋งŒ๋“ญ๋‹ˆ๋‹ค.

๋จผ์ € ์‹œ์ž‘๋œ ๋ถ€๋ชจ ํŠธ๋žœ์žญ์…˜์˜ ์ปค๋ฐ‹๊ณผ ๋กค๋ฐฑ์—๋Š” ์˜ํ–ฅ์„ ๋ฐ›์ง€๋งŒ ์ž์‹ ์˜ ์ปค๋ฐ‹๊ณผ ๋กค๋ฐฑ์€ ๋ถ€๋ชจ ํŠธ๋žœ์žญ์…˜์— ์˜ํ–ฅ์„ ์ฃผ์ง€ ์•Š์ฃ .

 

์˜ˆ๋ฅผ ๋“ค์–ด ๋กœ๊ทธ ํŒŒ์ผ์„ ์ €์žฅํ•˜๋Š” ๋กœ์ง์€ ๋ฉ”์ธ ๋กœ์ง์˜ ์ค‘์ฒฉ ํŠธ๋žœ์žญ์…˜์œผ๋กœ ์ง„ํ–‰ ๋  ์ˆ˜ ์žˆ๋Š”๋ฐ,

๋กœ๊ทธ ์ €์žฅ ๋กœ์ง์— ๋ฌธ์ œ๊ฐ€ ์žˆ์–ด๋„ ๋ฉ”์ธ ๋กœ์ง์€ ์‹คํ–‰์ด ๋˜์–ด์•ผ ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์˜ํ–ฅ์„ ์ฃผ๋ฉด ์•ˆ๋˜์ง€๋งŒ

๋ฉ”์ธ ๋กœ์ง์— ๋ฌธ์ œ๊ฐ€ ์žˆ์–ด์„œ ๋กค๋ฐฑ์„ ํ•˜๋ฉด ๋กœ๊ทธ ์ €์žฅ ๋กœ์ง์—๋„ ์˜ํ–ฅ์„ ์ค„ ์ˆ˜ ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

 

// AOP - Advice ๋“ฑ๋ก
DefaultTransactionAttribute defaultAttribute = new DefaultTransactionAttribute();
defaultAttribute.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);

// @Transactional
@Transactional(propagation = Propagation.PROPAGATION_REQUIRED)

 

 

โœ”๏ธ  Isolation

: ํŠธ๋žœ์žญ์…˜ ๊ฒฉ๋ฆฌ ์ˆ˜์ค€

 

ํŠธ๋žœ์žญ์…˜ ๊ฒฉ๋ฆฌ ์ˆ˜์ค€์€ ๋™์‹œ์— ์—ฌ๋Ÿฌ ํŠธ๋žœ์žญ์…˜์ด ์ง„ํ–‰๋  ๋•Œ,

ํŠธ๋žœ์žญ์…˜์˜ ์ž‘์—… ๊ฒฐ๊ณผ๋ฅผ ๋‹ค๋ฅธ ํŠธ๋žœ์žญ์…˜์—๊ฒŒ ์–ด๋–ป๊ฒŒ ๋…ธ์ถœํ•  ๊ฒƒ์ธ์ง€๋ฅผ ๊ฒฐ์ •ํ•˜๋Š” ๊ธฐ์ค€์ž…๋‹ˆ๋‹ค.

 

์˜ˆ๋ฅผ ๋“ค์–ด Transaction A๊ฐ€ ์ฝ๊ธฐ ์ž‘์—…์„ ํ•  ๋•Œ, Transaction B ๊ฐ€ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋Š๋ƒ,

ํ˜น์€ Transaction A๊ฐ€ Commit ์ „์ผ ๋•Œ Transaction B๊ฐ€ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋Š๋ƒ ๋ฅผ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค.

 

 

โœ…  DEFAULT

: ๋ฐ์ดํ„ฐ ์•ก์„ธ์Šค ๊ธฐ์ˆ  ๋˜๋Š” DB์˜ ๋””ํดํŠธ ์„ค์ •์„ ๋”ฐ๋ฆ…๋‹ˆ๋‹ค.

๋Œ€๋ถ€๋ถ„์˜ DB๋Š” READ_COMMITTED๋ฅผ ๊ธฐ๋ณธ ๊ฒฉ๋ฆฌ ์ˆ˜์ค€์œผ๋กœ ๊ฐ–์ง€๋งŒ,

๋ฐ์ดํ„ฐ ์•ก์„ธ์Šค ๊ธฐ์ˆ ์ด๋‚˜ DB๋งˆ๋‹ค ๋‹ค๋ฅผ ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— DB๋‚˜ ๋“œ๋ผ์ด๋ฒ„ ๋ฌธ์„œ๋ฅผ ์‚ดํŽด๋ณผ ํ•„์š”๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

 

โœ…  READ_UNCOMMITTED (level 0)

: ์ปค๋ฐ‹๋˜์ง€ ์•Š๋Š” ๋ฐ์ดํ„ฐ์— ๋Œ€ํ•œ ์ฝ๊ธฐ ํ—ˆ์šฉ

Dirty Read๊ฐ€ ๋ฐœ์ƒ ๊ฐ€๋Šฅ
๊ฐ€์žฅ ๋‚ฎ์€ ๊ฒฉ๋ฆฌ ์ˆ˜์ค€์ž…๋‹ˆ๋‹ค. ํ•˜๋‚˜์˜ ํŠธ๋žœ์žญ์…˜์ด ์ปค๋ฐ‹๋˜๊ธฐ ์ „์— ๊ทธ ๋ณ€ํ™”๊ฐ€ ๋‹ค๋ฅธ ํŠธ๋žœ์žญ์…˜์— ๊ทธ๋Œ€๋กœ ๋…ธ์ถœ๋˜๋Š” ๋ฌธ์ œ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

ํ•˜์ง€๋งŒ ๊ฐ€์žฅ ๋น ๋ฅด๊ธฐ ๋•Œ๋ฌธ์— ๋ฐ์ดํ„ฐ์˜ ์ผ๊ด€์„ฑ์ด ์กฐ๊ธˆ ๋–จ์–ด์ง€๋”๋ผ๋„ ์„ฑ๋Šฅ์„ ๊ทน๋Œ€ํ™”ํ•  ๋•Œ ์˜๋„์ ์œผ๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

โœ…  READ_COMMITTED (level 1)

: ์ปค๋ฐ‹๋œ ๋ฐ์ดํ„ฐ์— ๋Œ€ํ•œ ์ฝ๊ธฐ ํ—ˆ์šฉ

-Dirty Read ๋ฐฉ์ง€
๊ฐ€์žฅ ๋งŽ์ด ์‚ฌ์šฉ๋˜๋Š” ๊ฒฉ๋ฆฌ ์ˆ˜์ค€์œผ๋กœ, ์ปค๋ฐ‹๋˜์ง€ ์•Š์€ ์ •๋ณด๋Š” ์ฝ์„ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

๋Œ€์‹  ํ•˜๋‚˜์˜ ํŠธ๋žœ์žญ์…˜์ด ์ฝ์€ ๋กœ์šฐ๋ฅผ ๋‹ค๋ฅธ ํŠธ๋žœ์žญ์…˜์ด ์ˆ˜์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋”ฐ๋ผ์„œ, ํŠธ๋žœ์žญ์…˜์ด ๊ฐ™์€ ๋กœ์šฐ๋ฅผ ๋‹ค์‹œ ์ฝ์—ˆ์„ ๋•Œ ๋‹ค๋ฅธ ๋‚ด์šฉ์ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

โœ…  REPEATABLE_READ (level 2)

: ๋™์ผ ํ•„๋“œ์— ๋Œ€ํ•ด ๋‹ค์ค‘ ์ ‘๊ทผ ์‹œ ๋ชจ๋‘ ๋™์ผํ•œ ๊ฒฐ๊ณผ๋ฅผ ๋ณด์žฅ

Non-Repeatable Read ๋ฐฉ์ง€
ํ•˜๋‚˜์˜ ํŠธ๋žœ์žญ์…˜์ด ์ฝ์€ ๋กœ์šฐ๋ฅผ ๋‹ค๋ฅธ ํŠธ๋žœ์žญ์…˜์ด ์ˆ˜์ •ํ•˜๋Š” ๊ฒƒ์„ ๋ง‰์ง€๋งŒ, ์ƒˆ๋กœ์šด ๋กœ์šฐ๋ฅผ ์ถ”๊ฐ€ํ•˜๋Š” ๊ฒƒ์€ ์ œํ•œํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

๋”ฐ๋ผ์„œ SELECT๋กœ ์กฐ๊ฑด์— ๋งž๋Š” ๋กœ์šฐ๋ฅผ ์ „๋ถ€ ๊ฐ€์ ธ์˜ค๋Š” ๊ฒฝ์šฐ, ํŠธ๋žœ์žญ์…˜์ด ๋๋‚˜๊ธฐ ์ „์— ์ƒˆ๋กœ ์ถ”๊ฐ€๋œ ๋กœ์šฐ๊ฐ€ ๋ฐœ๊ฒฌ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

โœ…  SERIALIZABLE (level 3)

: ์ฝ๊ธฐ ์ž‘์—…์—๋„ ๊ณต์œ  ์ž ๊ธˆ์„ ์„ค์ •ํ•˜๊ฒŒ ๋˜๊ณ , ๋‹ค๋ฅธ ํŠธ๋žœ์žญ์…˜์—์„œ ๋ณ€๊ฒฝํ•˜์ง€ ๋ชปํ•จ

ํŠธ๋žœ์žญ์…˜์ด ์™„๋ฃŒ๋  ๋•Œ๊นŒ์ง€ SELECT ๋ฌธ์žฅ์ด ์‚ฌ์šฉํ•˜๋Š” ๋ชจ๋“  ๋ฐ์ดํ„ฐ์— shared lock์ด ๊ฑธ๋ฆฌ๋ฏ€๋กœ

๋‹ค๋ฅธ ์‚ฌ์šฉ์ž๋Š” ๊ทธ ์˜์—ญ์— ํ•ด๋‹น๋˜๋Š” ๋ฐ์ดํ„ฐ์— ๋Œ€ํ•œ ์ˆ˜์ • ๋ฐ ์ž…๋ ฅ์ด ๋ถˆ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.

๊ฐ€์žฅ ์•ˆ์ „ํ•œ ๊ฒฉ๋ฆฌ์ˆ˜์ค€์ด์ง€๋งŒ ๊ฐ€์žฅ ์„ฑ๋Šฅ์ด ๋–จ์–ด์ง€๊ธฐ ๋•Œ๋ฌธ์— ๊ทน๋‹จ์ ์œผ๋กœ ์•ˆ์ „ํ•œ ์ž‘์—…์ด ํ•„์š”ํ•œ ๊ฒฝ์šฐ๊ฐ€ ์•„๋‹ˆ๋ผ๋ฉด ์ž์ฃผ ์‚ฌ์šฉ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

 

// AOP - Advice ๋“ฑ๋ก
DefaultTransactionAttribute defaultAttribute = new DefaultTransactionAttribute(TransactionDefinition.PROPAGATION_REQUIRED);
defaultAttribute.setIsolationLevel(1);

// @Transactional
@Transactional(isolation = Isolation.READ_UNCOMMITTED)

 

โœ”๏ธ  Timeout

: ํŠธ๋žœ์žญ์…˜ ์ œํ•œ์‹œ๊ฐ„

 

์ดˆ ๋‹จ์œ„๋กœ ์ œํ•œ ์‹œ๊ฐ„์„ ์ง€์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋””ํดํŠธ๋Š” ์‹œ์Šคํ…œ์˜ ์ œํ•œ ์‹œ๊ฐ„์„ ๋”ฐ๋ฅด๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์ง์ ‘ ์ง€์ •ํ•˜๋Š” ๊ฒฝ์šฐ ์ด ๊ธฐ๋Šฅ์„ ์ง€์›ํ•˜์ง€ ๋ชปํ•˜๋Š” ์ผ๋ถ€ ํŠธ๋žœ์žญ์…˜ ๋งค๋‹ˆ์ €๋Š” ์˜ˆ์™ธ๋ฅผ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

 

โœ”๏ธ  ReadOnly

: ํŠธ๋žœ์žญ์…˜ ์ฝ๊ธฐ ์ „์šฉ

 

ํŠธ๋žœ์žญ์…˜์„ ์ฝ๊ธฐ ์ „์šฉ์œผ๋กœ ์„ค์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์„ฑ๋Šฅ์„ ์ตœ์ ํ™”ํ•˜๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉํ•  ์ˆ˜๋„ ์žˆ๊ณ ,

ํŠน์ • ํŠธ๋žœ์žญ์…˜ ์ž‘์—… ์•ˆ์—์„œ ์“ฐ๊ธฐ ์ž‘์—…์ด ์ผ์–ด๋‚˜๋Š” ๊ฒƒ์„ ์˜๋„์ ์œผ๋กœ ๋ฐฉ์ง€ํ•˜๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.

 

ํ•˜์ง€๋งŒ ์ผ๋ถ€ ํŠธ๋žœ์žญ์…˜ ๋งค๋‹ˆ์ €์˜ ๊ฒฝ์šฐ ์ฝ๊ธฐ ์ „์šฉ ์†์„ฑ์„ ๋ฌด์‹œํ•  ์ˆ˜๋„ ์žˆ์œผ๋‹ˆ ์ฃผ์˜ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

์ผ๋ฐ˜์ ์œผ๋กœ INSERT, UPDATE, DELETE ๊ฐ™์€ ์“ฐ๊ธฐ ์ž‘์—…์ด ์ง„ํ–‰๋˜๋ฉด ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.

 

์„ฑ๋Šฅ์„ ์œ„ํ•ด queryservice ํ•˜์œ„์˜ ๋ฉ”์„œ๋“œ์—์„œ ์ฃผ๋กœ ์‚ฌ์šฉํ•˜๊ธฐ๋„ ํ•ฉ๋‹ˆ๋‹ค.

 

โœ”๏ธ RollbackFor

RollbackFor, RollbackForClassName

ํŠธ๋žœ์žญ์…˜ ๋กค๋ฐฑ ๋Œ€์ƒ ์ง€์ •

 

์„ ์–ธ์  ํŠธ๋žœ์žญ์…˜์—์„œ๋Š” ๋Ÿฐํƒ€์ž„ ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด ๋กค๋ฐฑํ•ฉ๋‹ˆ๋‹ค.
์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒํ•˜์ง€ ์•Š๊ฑฐ๋‚˜ ์ฒดํฌ ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด ์ปค๋ฐ‹ํ•ฉ๋‹ˆ๋‹ค.

 

์ฒดํฌ ์˜ˆ์™ธ๋ฅผ ์ปค๋ฐ‹ ๋Œ€์ƒ์œผ๋กœ ์‚ผ๋Š” ์ด์œ ๋Š” ์ฒดํฌ์˜ˆ์™ธ๊ฐ€ ์˜ˆ์™ธ์ ์ธ ์ƒํ™ฉ์—์„œ ์‚ฌ์šฉ๋˜๊ธฐ ๋ณด๋‹ค๋Š”,

๋ฆฌํ„ด๊ฐ’์„ ๋Œ€์‹ ํ•ด์„œ ๋น„์ฆˆ๋‹ˆ์Šค ์ ์ธ ์˜๋ฏธ๋ฅผ ๋‹ด์€ ๊ฒฐ๊ณผ๋ฅผ ๋Œ๋ ค์ฃผ๋Š” ์šฉ๋„๋กœ ๋งŽ์ด ์‚ฌ์šฉ๋˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.

 

์Šคํ”„๋ง์—์„œ๋Š” ๋ฐ์ดํ„ฐ ์•ก์„ธ์Šค ๊ธฐ์ˆ ์˜ ์˜ˆ์™ธ๋Š” ๋Ÿฐํƒ€์ž„ ์˜ˆ์™ธ(์–ธ์ฒดํฌ ์˜ˆ์™ธ)๋กœ ์ „ํ™˜๋˜์–ด์„œ

๋˜์ ธ์ง€๋ฏ€๋กœ ๋Ÿฐํƒ€์ž„ ์˜ˆ์™ธ๋งŒ ๋กค๋ฐฑ ๋Œ€์ƒ์œผ๋กœ ์‚ผ์€ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

 

ํ•˜์ง€๋งŒ ์›ํ•œ๋‹ค๋ฉด ๊ธฐ๋ณธ ๋™์ž‘๋ฐฉ์‹์„ ๋ฐ”๊ฟ€ ์ˆ˜ ์žˆ๋Š”๋ฐ์š”.

๋ฐ”๋กœ ์ด RollbackFor, RollbackForClassName์†์„ฑ์„ ์ด์šฉํ•ด์„œ ์„ค์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ฒดํฌ ์˜ˆ์™ธ์ง€๋งŒ ๋กค๋ฐฑ ๋Œ€์ƒ์œผ๋กœ ์‚ผ์•„ํ– ํ•˜๋Š” ๊ฒƒ์ด ์žˆ๋‹ค๋ฉด ์ด ์†์„ฑ์— Rollback์„ ์ ์šฉํ•  ์˜ˆ์™ธ๋ฅผ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค.

 

 

// AOP - Advice ๋“ฑ๋ก
List<RollbackRuleAttribute> rollbackRules = new ArrayList<>();
rollbackRules.add(new RollbackRuleAttribute(Exception.class));

RuleBasedTransactionAttribute masterAttribute = new RuleBasedTransactionAttribute();
masterAttribute.setRollbackRules(rollbackRules);

// @Transactional
@Transactional(rollbackFor = Exception.class)

 

โœ”๏ธ noRollbackFor

noRollbackFor, noRollbackForClassName

ํŠธ๋žœ์žญ์…˜ ๋กค๋ฐฑ ์˜ˆ์™ธ ๋Œ€์ƒ ์ง€์ •

 

์œ„์™€๋Š” ๋ฐ˜๋Œ€๋กœ, ๊ธฐ๋ณธ์ ์œผ๋กœ ๋กค๋ฐฑ ๋Œ€์ƒ์ธ ๋Ÿฐํƒ€์ž„ ์˜ˆ์™ธ๋ฅผ ์ œ์™ธ์‹œํ‚ค๊ณ  ์‹ถ์„ ๋•Œ ์‚ฌ์šฉํ•˜๋Š” ์†์„ฑ์ž…๋‹ˆ๋‹ค.

๋กค๋ฐฑ ๋Œ€์ƒ์˜ ์˜ˆ์™ธ๋ฅผ ์ปค๋ฐ‹ ๋Œ€์ƒ์œผ๋กœ ์ง€์ •ํ•ด์ค๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด

 

@Transactional(noRollbackFor = MyCustomException.class)
public void myTransactionalMethod() {
    // ์˜ˆ์™ธ ๋ฐœ์ƒ ๊ฐ€๋Šฅํ•œ ์ฝ”๋“œ
}

 

์œ„์™€ ๊ฐ™์ด ์„ ์–ธํ•˜๋ฉด MyCustomException ํด๋ž˜์Šค์™€ ๊ทธ ํ•˜์œ„ ํด๋ž˜์Šค์— ๋Œ€ํ•ด์„œ๋Š”

๋กค๋ฐฑ์„ ์ˆ˜ํ–‰ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

 

 

 

 

 

 

 

 

 

 

 

์ถœ์ฒ˜ : https://gngsn.tistory.com/152