๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
Spring/JPA

@Transactional ํŠน์ง•, ์‚ฌ์šฉ๋ฐฉ๋ฒ•, ์ฃผ์˜์ 

by ํ‘์‹œ๋ฐ” 2023. 8. 15.

๐Ÿ˜ค ๋ฐฐ๊ฒฝ

์Šคํ”„๋ง์—์„œ ํŠธ๋žœ์žญ์…˜ ์ฒ˜๋ฆฌ๊ฐ€ ํ•„์š”ํ•œ ๊ฒฝ์šฐ, ๋‚˜๋Š” ๊ฐ„๋‹จํ•˜๊ฒŒ JPA์™€ ํ•จ๊ป˜ @Transactional ์–ด๋…ธํ…Œ์ด์…˜์„ ํด๋ž˜์Šค ํ˜น์€ ๋ฉ”์„œ๋“œ์— ์„ค์ •ํ•ด ์™”๋‹ค. ๊ทธ๋Ÿฌ๋˜ ์ค‘ ์ตœ๊ทผ ์šด์˜ ์ค‘์ธ ์„œ๋น„์Šค์—์„œ Transaction Lock ์ด์Šˆ๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด์„œ ๋ฌธ๋“ ์ด๋ ‡๊ฒŒ ๋ง‰ ์‚ฌ์šฉํ•˜๋Š” ๊ฒŒ ์˜ณ์€ ์ผ์ธ๊ฐ€๋ฅผ ๊ณ ๋ฏผํ•˜๊ฒŒ ๋˜์—ˆ๊ณ , ์กฐ์‚ฌ ๋ฐ ์ •๋ฆฌ ์ฐจ์›์—์„œ ํ•ด๋‹น ๋‚ด์šฉ์— ๋Œ€ํ•ด ์ž‘์„ฑํ•˜๊ฒŒ ๋˜์—ˆ๋‹ค.

 

ํ•ด๋‹น ํฌ์ŠคํŒ…์—์„œ๋Š” @Transactional ๊ฐœ๋…๊ณผ ์›๋ฆฌ๋ณด๋‹ค๋Š” ํŠน์ง•, ์‚ฌ์šฉ ๋ฐฉ๋ฒ•, ์ฃผ์˜์ ์— ๋Œ€ํ•ด์„œ ๊ฐ„๋‹จํ•˜๊ฒŒ ์„ค๋ช…ํ•˜๊ณ ์ž ํ•œ๋‹ค.

1. ํŠน์ง•

@Transactional์€ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ํŠน์ง•์„ ๊ฐ€์ง€๊ณ  ์žˆ๋‹ค.

 

- AOP๋ฅผ ํ†ตํ•ด ๊ตฌํ˜„๋˜์—ˆ๋‹ค.

- ์–ด๋…ธํ…Œ์ด์…˜์ด ์„ ์–ธ๋œ ํด๋ž˜์Šค์— ํŠธ๋žœ์žญ์…˜์ด ์ ์šฉ๋œ ํ”„๋ก์‹œ ๊ฐ์ฒด๊ฐ€ ์ƒ์„ฑ๋œ๋‹ค.

- CheckedException ๋˜๋Š” ์˜ˆ์™ธ๊ฐ€ ์—†๋Š” ๊ฒฝ์šฐ๋Š” ๋ฉ”์„œ๋“œ๊ฐ€ ์ข…๋ฃŒ๋˜๋ฉด์„œ Commit ์ฒ˜๋ฆฌ๋œ๋‹ค. 
- UncheckedException๊ฐ€ ๋ฐœ์ƒํ•˜๋Š” ๊ฒฝ์šฐ๋Š” Rollback ์ฒ˜๋ฆฌ๋œ๋‹ค.

- Proxy Mode๊ฐ€ Default๋กœ ์„ค์ •๋˜์–ด์žˆ๋‹ค.

2. ์‚ฌ์šฉ ๋ฐฉ๋ฒ•

@Transactional ์–ด๋…ธํ…Œ์ด์…˜์„ ์‚ดํŽด๋ณด๋ฉด ์•Œ ์ˆ˜ ์žˆ๋“ฏ์ด ์ผ๋ฐ˜์ ์œผ๋กœ Service Layer์— ํด๋ž˜์Šค ๋˜๋Š” ๋ฉ”์„œ๋“œ์— ์ ์šฉํ•œ๋‹ค.

Repository Layer์—๋„ ์„ ์–ธ ๊ฐ€๋Šฅํ•˜์ง€๋งŒ ์„ ํ˜ธํ•˜์ง€ ์•Š๋Š” ๋ฐฉ๋ฒ•์ด๋‹ค. (์Šคํ”„๋ง ๊ณต์‹ ๋ฌธ์„œ)

 

๊ฐœ์ธ์ ์œผ๋กœ ์„ ํ˜ธํ•˜๋Š” ๋ฐฉ์‹์€ ํด๋ž˜์Šค ๋‹จ์— @Transactional(readOnly = true) readOnly ์˜ต์…˜์„ ๋ถ€์—ฌํ•ด์„œ ์„ ์–ธํ•˜๊ณ ,

Create, Update, Delete๊ฐ€ ํ•„์š”ํ•œ ๊ฒฝ์šฐ์—๋Š” ๋ฉ”์„œ๋“œ ๋‹จ์— @Transactional์„ ์„ ์–ธํ•œ๋‹ค.

Why?

๊ฐœ๋ฐœ ๊ณผ์ •์—์„œ ์‹ค์ˆ˜๋กœ readOnly ์˜ต์…˜์„ ์ ์šฉํ•˜์ง€ ์•Š์„ ์ˆ˜๋„ ์žˆ๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค. readOnly๋Š” JPA์™€ ์‚ฌ์šฉํ•  ๋•Œ CUD ์ฒ˜๋ฆฌ๋ฅผ ์ œ์™ธํ•จ์œผ๋กœ์จ(์Šค๋ƒ…์ƒท ๊ด€๋ฆฌ X) ์กฐํšŒ ์„ฑ๋Šฅ์„ ํ–ฅ์ƒํ•  ์ˆ˜ ์žˆ๋Š” ์ค‘์š”ํ•œ ์˜ต์…˜์ด๋‹ค. ๊ทธ๋Ÿฌ๋ฏ€๋กœ CUD ๊ณผ์ •์ด ํ•„์š”ํ•œ ๊ฒฝ์šฐ ๋ณ„๋„๋กœ ๋ฉ”์„œ๋“œ์— @Transactional์„ ์„ ์–ธํ•จ์œผ๋กœ์จ ์‹ค์ˆ˜๋ฅผ ๋ฐฉ์ง€ํ•  ์ˆ˜ ์žˆ๋‹ค.

 

readOnly๋Š” ์„ฑ๋Šฅ ํ–ฅ์ƒ ์˜ต์…˜๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ์„œ๋น„์Šค์—์„œ Mater(CRUD), Slave(Read Only)๋กœ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋ฅผ ๋ถ„๋ฆฌ ๊ตฌ์„ฑํ•˜๋Š” ๊ฒฝ์šฐ, ํ•ด๋‹น ์˜ต์…˜์„ ๋ฐ”ํƒ•์œผ๋กœ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์—”๋“œํฌ์ธํŠธ๋ฅผ ๋‹ค๋ฅด๊ฒŒ ์ ์šฉํ•  ์ˆ˜๋„ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์ค‘์š” ์š”์†Œ์ด๋‹ค.

3. ์ฃผ์˜์ 

- ์™ธ๋ถ€ API ์š”์ฒญ์ด ์žˆ๋Š” ๊ฒฝ์šฐ๋Š” @Transactional ์‚ฌ์šฉ์„ ๊ณ ๋ฏผํ•˜์ž.

 

์™ธ๋ถ€ API ์š”์ฒญ์€ ๊ธฐ๋ณธ์ ์œผ๋กœ ๋ฆฌ์†Œ์Šค๊ฐ€ ๋งŽ์ด ๋“ค๊ณ  ์‹œ๊ฐ„์ด ์˜ค๋ž˜ ๊ฑธ๋ฆฌ๋Š” ์ž‘์—…์ด๋‹ค. ๊ทธ๋Ÿฐ๋ฐ ๋งŒ์•ฝ API ์ฒ˜๋ฆฌ๊ฐ€ ์žˆ๋Š” ์„œ๋น„์Šค ๋ฉ”์„œ๋“œ์— @Transactional์„ ์„ ์–ธํ•œ๋‹ค๋ฉด, ํ•ด๋‹น ์„œ๋น„์Šค ๋ฉ”์„œ๋“œ๊ฐ€ ์ข…๋ฃŒ๋  ๋•Œ๊นŒ์ง€ ํŠธ๋žœ์žญ์…˜์ด ์žกํ˜€์žˆ์„ ๊ฒƒ์ด๋ฏ€๋กœ ์„ฑ๋Šฅ ์ƒ์œผ๋กœ ๋ฌธ์ œ๊ฐ€ ์—†์„์ง€ ๊ณ ๋ฏผํ•ด๋ณด์•„์•ผ ํ•œ๋‹ค. 

 

- Propagation.REQUIRES_NEW๋Š” ์ƒˆ๋กœ์šด ํด๋ž˜์Šค์— ์„ ์–ธํ•ด์„œ ์‚ฌ์šฉํ•˜์ž.

 

์ƒˆ๋กœ์šด ํŠธ๋žœ์žญ์…˜(Propagation.REQUIRES_NEW)์€ ๋™์ผํ•œ ํด๋ž˜์Šค ๋‚ด ๋ฉ”์„œ๋“œ์—์„œ ํ˜ธ์ถœํ•˜๋ฉด ์ƒˆ๋กœ ์ƒ์„ฑ๋˜์ง€ ์•Š๋Š”๋‹ค. ๋ฐ˜๋“œ์‹œ ๋‹ค๋ฅธ ํด๋ž˜์Šค์—์„œ ์„ ์–ธํ•˜๊ณ  ํ˜ธ์ถœํ•ด์•ผ ํ•œ๋‹ค.

 

์Šคํ”„๋ง ๊ณต์‹ ๋ฌธ์„œ์— ๋”ฐ๋ฅด๋ฉด, Default Proxy Mode(์Šคํ”„๋ง์—์„œ ๊ธฐ๋ณธ์œผ๋กœ ์‚ฌ์šฉํ•˜๋Š” Proxy)์—์„œ๋Š” ํ”„๋ก์‹œ๋ฅผ ํ†ตํ•ด ๋“ค์–ด์˜ค๋Š” ์™ธ๋ถ€(๋‹ค๋ฅธ ํด๋ž˜์Šค) ๋ฉ”์„œ๋“œ ํ˜ธ์ถœ๋งŒ ๊ฐ€๋กœ์ฑˆ๋‹ค๊ณ  ํ•œ๋‹ค. ์ฆ‰, ์ž์ฒด ํ˜ธ์ถœ(๋™์ผํ•œ ํด๋ž˜์Šค์—์„œ ๋‹ค๋ฅธ ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœ)์€ ํ˜ธ์ถœ๋œ ๋ฉ”์„œ๋“œ๊ฐ€ @Transactional๊ฐ€ ์žˆ์–ด๋„ ๋Ÿฐํƒ€์ž„ ์‹œ ์‹ค์ œ ํŠธ๋žœ์žญ์…˜์œผ๋กœ ์ด์–ด์ง€์ง€ ์•Š๋Š”๋‹ค.

 

๊ณต์‹ ๋ฌธ์„œ์— ์žˆ๋Š” ๋‚ด์šฉ์ด๋ฏ€๋กœ, ์ž์„ธํ•œ ์›๋ฆฌ์™€ ๋‚ด์šฉ์€ REFERENCE๋ฅผ ์ฐธ๊ณ ํ•˜์ž.

 

- public ๋ฉ”์„œ๋“œ์—์„œ๋งŒ ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•˜๋‹ค.

 

์Šคํ”„๋ง ํŠธ๋žœ์žญ์…˜ AOP ๊ธฐ๋Šฅ์€ public์—์„œ๋งŒ ํŠธ๋žœ์žญ์…˜์„ ์ ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ๊ธฐ๋ณธ ์„ค์ •์ด ๋˜์–ด์žˆ๋‹ค.

private, protected ๋ฉ”์„œ๋“œ์— ์„ ์–ธํ•˜๋ฉด ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•˜์ง€๋Š” ์•Š์ง€๋งŒ, ํŠธ๋žœ์žญ์…˜์ด ์ ์šฉ๋˜์ง€ ์•Š๋Š”๋‹ค.

 

- ์ดˆ๊ธฐํ™” ์‹œ์  ์ดํ›„์— ์ ์šฉ์ด ๊ฐ€๋Šฅํ•˜๋‹ค.

 

์Šคํ”„๋ง ํ”„๋ ˆ์ž„์›Œํฌ์—์„œ๋Š” ์ดˆ๊ธฐํ™” ์ฝ”๋“œ๊ฐ€ ์‹คํ–‰๋œ ๋’ค ํŠธ๋žœ์žญ์…˜ AOP๊ฐ€ ์ ์šฉ๋œ๋‹ค. ๊ทธ๋Ÿฌ๋ฏ€๋กœ @PostConstruct ์• ๋…ธํ…Œ์ด์…˜๊ณผ @Transactional ์• ๋…ธํ…Œ์ด์…˜์„ ๊ฐ™์ด ์‚ฌ์šฉํ•  ๊ฒฝ์šฐ ์˜ˆ์ƒ๊ณผ ๋‹ฌ๋ฆฌ ํŠธ๋žœ์žญ์…˜์ด ์ ์šฉ๋˜์ง€ ์•Š๋Š”๋‹ค.

REFERENCE

https://docs.spring.io/spring-framework/reference/data-access/transaction/declarative/annotations.html

 

Using @Transactional :: Spring Framework

The @Transactional annotation is metadata that specifies that an interface, class, or method must have transactional semantics (for example, "start a brand new read-only transaction when this method is invoked, suspending any existing transaction"). The de

docs.spring.io

 

๋Œ“๊ธ€