๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
๐Ÿ’ป ๋ฐฑ์—”๋“œ ๊ฐœ๋ฐœ/JPA - Hibernate

02. ๋‹น์‹ ์˜ @Transactional์˜ readOnly ์˜ต์…˜ ์ž˜ ์“ฐ๊ณ  ์žˆ๋‚˜์š”?

by YangsDev 2021. 2. 4.

์‹œ์ž‘ํ•˜๋ฉฐ

์˜ค๋Š˜์€ Spring์—์„œ ๋งˆ๋ฒ•์˜ ์–ด๋…ธํ…Œ์ด์…˜์ด๋ผ๊ณ  ๋ถ€๋ฅด๋Š” @Transactional์˜ readOnly ์˜ต์…˜์— ๋Œ€ํ•˜์—ฌ ์ด์•ผ๊ธฐํ•ด๋ณด๋ ค๊ณ  ํ•œ๋‹ค.

 

์—ฅ? @Transactional์—๋Š” readOnly๋ผ๋Š” ์˜ต์…˜์ด ์—†๋Š”๋ฐ?

์—ฅ?  @Transactional์—๋Š” readOnly ์˜ต์…˜์ด ์—†๋Š”๋ฐ ์ด๊ฒŒ ๋ฌด์Šจ์ผ์ด์ฃ ? ์—†๋Š” ๊ฑธ๋กœ ์ด์•ผ๊ธฐ๋ฅผ ํ•˜๋ ค๊ณ  ํ•˜๋Š” ๊ฑด๊ฐ€?

์šฐ๋ฆฌ๋Š” ์ด๋ฒˆ readOnly ์ด์•ผ๊ธฐ๋ฅผ ํ•˜๊ธฐ ์ „์— @Transactional์€ 2๊ฐ€์ง€ ์žˆ๋‹ค๋Š” ๊ฒƒ์„ ์ด์•ผ๊ธฐํ•˜๊ณ  ๋„˜์–ด๊ฐ€๋ ค๊ณ  ํ•œ๋‹ค.

์„œ๋กœ ๋‹ค๋ฅธ ํŒจํ‚ค์ง€๋ฅผ ๊ฐ€์ง„ 2๊ฐœ์˜ ์–ด๋…ธํ…Œ์ด์…˜

์ด 2๊ฐ€์ง€๊ฐ€ ๊ถ๊ทน์ ์œผ๋กœ ํ•˜๋ ค๊ณ  ํ•˜๋Š” ์ผ์€ ๋™์ผํ•˜๋‹ค.  (์‹ค์ œ Spring AOP ์ƒ์—์„œ๋Š”  javax ํŒจํ‚ค์ง€์˜ ํŠธ๋žœ์ ์…˜๊ณผ Spring ํŒจํ‚ค์ง€์˜ ํŠธ๋žœ์ ์…˜๋„ ๋ชจ๋‘ ์ง€์›ํ•˜๊ณ  ์žˆ๋‹ค.)  Spring ํŒจํ‚ค์ง€๋ฅผ ํ†ตํ•ด ์ œ๊ณต๋˜๋Š” ์–ด๋…ธํ…Œ์ด์…˜์ด ๋” ๋งŽ์€ ์˜ต์…˜์„ ์ œ๊ณตํ•˜๊ฒŒ ๋œ๋‹ค..

 

์ด ๊ธ€์—์„œ๋Š” readOnly๊ฐ€ ํ•˜๋Š” ์—ญํ• ์— ๋Œ€ํ•ด ์ด์•ผ๊ธฐ๋ฅผ  ํ•˜๋ ค๊ณ  ํ•˜๋‹ˆ, ์ž์„ธํ•œ ๋‚ด์šฉ์€ ๊ตฌ๊ธ€์—์„œ ์ฐพ์•„๋ณด๋„๋ก ํ•˜์ž (๋” ์ด์•ผ๊ธฐํ•˜๋ฉด ๋„ˆ๋ฌด ์‚ผ์ฒœํฌ๋กœ ๋งŽ์ด ๋น ์งˆ ๊ฒƒ ๊ฐ™์•„์„œ..)

 

 

@Transactional์˜ readOnly๋Š” ์–ด๋–ป๊ฒŒ ๋™์ž‘ํ• ๊นŒ?

@Transactional์˜ readOnly๊ฐ€ ์–ด๋–ป๊ฒŒ ๋™์ž‘ํ•˜๋Š”์ง€ ํƒํ—˜์„ ๋– ๋‚˜ ๋ด…์‹œ๋‹ค

์ผ๋‹จ readOnly ์˜ต์…˜์— ๋Œ€ํ•ด ์งš๊ณ  ๋„˜์–ด ๊ฐ€๋ณด๋„๋ก ํ•˜์ž

- ํŠธ๋žœ์ ์…˜์„ ์ฝ๊ธฐ ์ „์šฉ์œผ๋กœ ์„ค์ • ๊ฐ€๋Šฅํ•จ.

- ๊ฐœ๋ฐœ์ž์˜ ์‹ค์ˆ˜๋กœ ํ•ด๋‹น ํŠธ๋žœ์ ์…˜ ์•ˆ์—์„œ Write๊ฐ€ ๋ฐœ์ƒํ•˜๋Š” ๊ฒƒ์„ ๋ฐฉ์ง€๋  ์ˆ˜ ๋„ ์žˆ๊ณ , ์•ˆ๋  ์ˆ˜๋„ ์žˆ๋‹ค.  (JDBC Driver์— ๋”ฐ๋ผ ๋‹ค๋ฅด๋‹ค.)

 

๋จผ์ €, Spring ํŠธ๋žœ์ ์…˜์˜ readOnly ์˜ต์…˜์— ๋Œ€ํ•œ API ๋ฌธ์„œ๋ฅผ ๋จผ์ € ํ™•์ธํ•ด๋ณด๋„๋ก ํ•˜์ž.

 

Transactional (Spring Framework 5.3.3 API)

Defines zero (0) or more exception names (for exceptions which must be a subclass of Throwable), indicating which exception types must cause a transaction rollback. This can be a substring of a fully qualified class name, with no wildcard support at presen

docs.spring.io

This just serves as a hint for the actual transaction subsystem; it will not necessarily cause failure of write access attempts. A transaction manager which cannot interpret the read-only hint will not throw an exception when asked for a read-only transaction but rather silently ignore the hint.

๊ณต์‹๋ฌธ์„œ์—์„œ ํ•ด๋‹น ์˜ต์…˜์€ ์ด ์˜ต์…˜์ด ์ฝ๊ธฐ ์ „์šฉ ํžŒํŠธ๋ฅผ ์ œ๊ณตํ•œ๋‹ค.๋ผ๊ณ  ์ด์•ผ๊ธฐ๋ฅผ ํ•œ๋‹ค.

์ด๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ 'Connection.setReadOnly(true)'๋ฅผ ํ˜ธ์ถœํ•˜๊ฒŒ ๋œ๋‹ค. ์œ„์—์„œ '๋  ์ˆ˜ ๋„์žˆ๊ณ , ์•ˆ ๋  ์ˆ˜๋„ ์žˆ๋‹ค'๋ผ๊ณ  ์ด์•ผ๊ธฐ ํ•œ ์ด์œ ๋„ ์ด๋Ÿฌํ•œ ์ด์œ ๋‹ค. 

Oracle Driver์˜ ๊ฒฝ์šฐ๋Š” ์˜ˆ์ „๋ถ€ํ„ฐ readOnly ์˜ต์…˜์„ ์ œ๊ณตํ•˜์˜€์ง€๋งŒ, MySQL Driver๋Š” 5.6.5 ์ด์ƒ์ด ๋˜์–ด์•ผ ๋“œ๋””์–ด ์ง€์›๋˜์—ˆ๋‹ค๊ณ  ํ•œ๋‹ค.

๊ทธ ์™ธ์— H2์—์„œ๋Š” ์•„์ง ์ง€์›์„ ํ•˜์ง€ ์•Š๋Š”๋‹ค๊ณ ๋„ ํ•˜๊ณ , JDBC ์ œ์กฐ์‚ฌ ๋ณ„๋กœ ๋‹ค๋ฅด๊ฒŒ ์ ์šฉ๋œ๋‹ค๋Š” ์ ์„ ๊ผญ ์ธ์ง€ ํ•ด์•ผ ํ•œ๋‹ค.

(๊ด€๋ จ๋œ ์ฐธ๊ณ  ๊ธ€ : wonwoo.ml/index.php/post/839)

 

Hibernate๋กœ ์‚ฌ์šฉํ•  ๋•Œ๋Š” ์–ด๋–ป๊ฒŒ ์ ์šฉ๋ ๊นŒ?

Hibernate๋Š” readOnly ์˜ต์…˜์ด ์„ค์ •๋œ  ๊ฒฝ์šฐ๋Š” Session์˜ Flush Mode๋ฅผ 'FlushMode.MANUAL' ๋ชจ๋“œ๋กœ ์„ค์ •ํ•œ๋‹ค.

์ด๋Š” ๊ณง, '์ด ํŠธ๋žœ์ ์…˜์€ ์ปค๋ฐ‹ ์‹œ flush๋ฅผ ํ•˜์ง€ ์•Š๋Š”๋‹ค'๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•œ๋‹ค.

 

๊ฒฐ๊ตญ์€ Hibernate๋Š” Entity์— flush๋ฅผ ํ˜ธ์ถœํ•˜์ง€ ์•Š๊ฒŒ ๋˜๊ณ , ๋ณ€๊ฒฝ์€ ์ž์—ฐ์Šค๋Ÿฝ๊ฒŒ ๋ฌด์‹œ๋˜๊ฒŒ ๋œ๋‹ค.

๋˜ํ•œ, flush๊ฐ€ ํ˜ธ์ถœ๋˜์ง€ ์•Š๊ณ , Dirty Checking์„ ํ•˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— ์„ฑ๋Šฅ์ ์œผ๋กœ๋„ ์ด ์ ์„ ์–ป์„ ์ˆ˜ ์žˆ๋‹ค.

(Dirty Checking์ด ์ด๋ฃจ์–ด์ง€๋Š” ๊ณผ์ •์„ ์‰ฝ๊ฒŒ ์„ค๋ช…ํ•œ๋‹ค๊ณ  ํ•˜๋ฉด, Entity์™€ Snapshot์„ ๋น„๊ตํ•˜๊ฒŒ ๋˜๋Š”๋ฐ ์ด๋Ÿฌํ•œ ๊ณผ์ •์ด ์ƒ๋žต๋˜๊ฒŒ ๋˜๋ฉด์„œ ์„ฑ๋Šฅ ์ƒ์˜ ์ด์ ์„ ์–ป๊ฒŒ ๋œ๋‹ค.)

 

๋Œ“๊ธ€