JiwonDev

์˜์‹์˜ ํ๋ฆ„๋Œ€๋กœ ์จ๋ณด๋Š” DB ํŠธ๋žœ์žญ์…˜ ์ด์•ผ๊ธฐ

by JiwonDev

์ธ๋„ค์ผ์šฉ '-'

๐ŸŽฏ  ๋ฌด๊ฒฐ์„ฑ๊ณผ ์ •ํ•ฉ์„ฑ?

๋ฌด๊ฒฐ์„ฑ(Integrity) : ํ ์ด ์—†์ด ์˜จ์ „ํ•จ. ๋ฐ์ดํ„ฐ ๊ฐ’์ด ์ •ํ™•ํ•œ ์ƒํƒœ์ธ๊ฐ€ ํ˜น์‹œ ์†์ƒ๋˜์—ˆ๊ฑฐ๋‚˜ ์ด์ƒํ•œ ๊ฐ’์ด ๋“ค์–ด๊ฐ€์žˆ์ง€๋Š” ์•Š๋Š”๊ฐ€?

์ •ํ•ฉ์„ฑ(Consistency) : ๋ชจ๋“  ํŠธ๋žœ์žญ์…˜์—์„œ [ ๊ฐ™์€ ๋ฐ์ดํ„ฐ๊ฐ’ ]์ด ๋ชจ์ˆœ ์—†์ด ์ผ์น˜ํ•œ๊ฐ€

[ ๋ฌด๊ฒฐ์„ฑ๊ณผ ์ •ํ•ฉ์„ฑ์ด ๋Œ€์ฒด ๋ญ์ฃ ? ]

๋”๋ณด๊ธฐ

์€ํ–‰ DB์— 'ํ™๊ธธ๋™' ์ด๋ผ๋Š” ๊ณ ๊ฐ์˜ ์ž”์•ก์€ 0์› ์ด์ƒ์ด์–ด์•ผ ํ•œ๋‹ค.

 

Case1
- ์ฃผ๋ฌธ์ •๋ณด ํ…Œ์ด๋ธ”์— ํ™๊ธธ๋™์˜ ์ž”์•ก์€ -10 ์ด๋‹ค. (๋ฌด๊ฒฐ์„ฑ์ด ๊นจ์กŒ๋‹ค)
- ํ•˜์ง€๋งŒ ๊ณ ๊ฐ์ •๋ณด ํ…Œ์ด๋ธ”์—๋„ ํ™๊ธธ๋™์˜ ์ž”์•ก์€ -10์ด๋‹ค. (์ •ํ•ฉ์„ฑ๋งŒ ์ผ์น˜ํ•œ๋‹ค.) 

Case2

- ์ฃผ๋ฌธ์ •๋ณด ํ…Œ์ด๋ธ”์— ํ™๊ธธ๋™ ์ž”์•ก์€ 10,000 ์ด๋‹ค. (๋ฌด๊ฒฐ์„ฑ์€ ๋ฌธ์ œ์—†๋‹ค.)

- ํ•˜์ง€๋งŒ ๊ณ ๊ฐ์ •๋ณด ํ…Œ์ด๋ธ”์—์„œ์˜ ํ™๊ธธ๋™ ์ž”์•ก์€ 2000 ์ด๋‹ค. (์ •ํ•ฉ์„ฑ๋งŒ ๊นจ์กŒ๋‹ค.)

 

์ด๋Ÿฌํ•œ ๋ฌด๊ฒฐ์„ฑ๊ณผ ์ •ํ•ฉ์„ฑ์„, ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์—์„  ํ…Œ์ด๋ธ” '์ œ์•ฝ์กฐ๊ฑด'์œผ๋กœ ๋ง‰์„ ์ˆ˜ ์žˆ๋‹ค.
๋ฌผ๋ก  ์ œ์•ฝ์กฐ๊ฑด์„ ๊ฑธ๋ฉด ๊ทธ๋งŒํผ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์˜ ์„ฑ๋Šฅ์€ ๋‚˜๋น ์ง€๊ณ , ํ…Œ์ด๋ธ”์„ ์œ ์—ฐํ•˜๊ฒŒ ๋ณ€๊ฒฝํ•˜๊ธฐ ์–ด๋ ค์›Œ์ง„๋‹ค.

 

์—”ํ‹ฐํ‹ฐ ๋ฌด๊ฒฐ์„ฑ(Entity Integrity) ์—”ํ‹ฐํ‹ฐ๋Š” ๊ฐ ์ธ์Šคํ„ด์Šค๋ฅผ ์œ ์ผํ•˜๊ฒŒ ์‹๋ณ„ํ•  ์ˆ˜ ์žˆ๋Š” ์†์„ฑ์ด๋‚˜ ์†์„ฑ ๊ทธ๋ฃน์„ ๊ฐ€์ ธ์•ผ ํ•œ๋‹ค.
๋„๋ฉ”์ธ ๋ฌด๊ฒฐ์„ฑ(Domain Integrity) ์นผ๋Ÿผ ๋ฐ์ดํ„ฐ ํƒ€์ž…, ๊ธธ์ด, ์œ ํšจ ๊ฐ’์ด ์ผ๊ด€๋˜๊ฒŒ ์œ ์ง€๋˜์–ด์•ผ ํ•œ๋‹ค.
์ฐธ์กฐ ๋ฌด๊ฒฐ์„ฑ(Referential Integrity) ๋ฐ์ดํ„ฐ ๋ชจ๋ธ์—์„œ ์ •์˜๋œ ์‹ค์ฒด ๊ฐ„์˜ ๊ด€๊ณ„ ์กฐ๊ฑด์„ ์œ ์ง€ํ•˜๋Š” ๊ฒƒ์ด๋‹ค.
์—…๋ฌด ๋ฌด๊ฒฐ์„ฑ(Business Integrity) ๋‹ค์–‘ํ•˜๊ฒŒ ์ •์˜๋  ์ˆ˜ ์žˆ๋Š” ๋น„์ฆˆ๋‹ˆ์Šค ๊ทœ์น™์ด ๋ฐ์ดํ„ฐ์ ์œผ๋กœ ์ผ๊ด€์„ฑ์„ ์œ ์ง€ํ•˜๋Š” ๊ฒƒ์ด๋‹ค.

 

 

๐ŸŽฏ  ํŠธ๋žœ์žญ์…˜?

ํŠธ๋žœ์žญ์…˜์ด๋ž€ ๋ฐ์ดํ„ฐ๋ฅผ ์กฐ์ž‘ํ•˜๋Š” ACID ํ•œ ์ž‘์—… ๋‹จ์œ„์ด๋‹ค.
[ ACID ํ•œ ์ž‘์—…๋‹จ์œ„๋ผ๋Š”๊ฒŒ ๋ฌด์Šจ ๋ง์ด์ฃ ? ]

๋”๋ณด๊ธฐ

 Atomicity(์›์ž์„ฑ) - ์ž‘์—…๋‹จ์œ„, ์ฆ‰ ํŠธ๋žœ์žญ์…˜์„ ๋” ์ด์ƒ ์ž‘์€ ๋‹จ์œ„๋กœ ์ชผ๊ฐค ์ˆ˜ ์—†๋‹ค.

  • ํ•œ ํŠธ๋žœ์žญ์…˜ ๋‚ด์˜ ๋ชจ๋“  ๋ช…๋ น์€ ๋ฐ˜๋“œ์‹œ ์™„๋ฒฝํžˆ ์ˆ˜ํ–‰๋˜์–ด์•ผ ํ•˜๋ฉฐ, ๋ชจ๋‘๊ฐ€ ์™„๋ฒฝํžˆ ์ˆ˜ํ–‰๋˜์ง€ ์•Š๊ณ  ์–ด๋Šํ•˜๋‚˜๋ผ๋„ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด ํŠธ๋žœ์žญ์…˜ ์ „๋ถ€๊ฐ€ ์ทจ์†Œ๋˜์–ด์•ผ ํ•œ๋‹ค. ๋ถ€๋ถ„ ์™„๋ฃŒ๋Š” ๋ถˆ๊ฐ€๋Šฅํ•˜๋‹ค.
  • ๋ณดํ†ต ํŠธ๋žœ์žญ์…˜ ์„ฑ๊ณต ์—ฐ์‚ฐ์„ Commit(์ปค๋ฐ‹), ์‹คํŒจ ์—ฐ์‚ฐ์„ Rollback(๋˜๋Š” Aborted) ๋ผ ๋ถ€๋ฅธ๋‹ค.

Consistency(์ •ํ•ฉ์„ฑ) - ํŠธ๋žœ์žญ์…˜์€ ์–ธ์ œ๋‚˜ ๊ฐ™์€ ์ž…๋ ฅ์—๋Š” ๊ฐ™์€ ๊ฒฐ๊ณผ๊ฐ€ ๋‚˜์™€์•ผํ•œ๋‹ค.

  • ์‹œ์Šคํ…œ์ด ๊ฐ€์ง€๊ณ  ์žˆ๋Š” ๊ณ ์ •์š”์†Œ(์ œ์•ฝ์กฐ๊ฑด)๋“ค์€ ํŠธ๋žœ์žญ์…˜ ์ˆ˜ํ–‰ ์ „๊ณผ ํŠธ๋žœ์žญ์…˜ ์ˆ˜ํ–‰ ์™„๋ฃŒ ํ›„์˜ ์ƒํƒœ๊ฐ€ ๊ฐ™์•„์•ผ ํ•œ๋‹ค.

Isolation(๋…๋ฆฝ์„ฑ,๊ฒฉ๋ฆฌ์„ฑ) - ๊ฐ๊ฐ์˜ ํŠธ๋žœ์žญ์…˜์€ ๋…๋ฆฝ์ ์ด๋‹ค. ์‹คํ–‰ ์ค‘ ์„œ๋กœ ์˜ํ–ฅ๋ผ์น˜์ง€ ์•Š๋Š”๋‹ค.

  • ๋‘˜ ์ด์ƒ์˜ ํŠธ๋žœ์žญ์…˜์ด ๋™์‹œ์— ๋ณ‘ํ–‰ ์‹คํ–‰๋˜๋Š” ๊ฒฝ์šฐ ์–ด๋Š ํ•˜๋‚˜์˜ ํŠธ๋žœ์žญ์…˜ ์‹คํ–‰์ค‘์— ๋‹ค๋ฅธ ํŠธ๋žœ์žญ์…˜์˜ ์—ฐ์‚ฐ์ด ๋ผ์–ด๋“ค ์ˆ˜ ์—†๋‹ค.
  • ์ˆ˜ํ–‰์ค‘์ธ ํŠธ๋žœ์žญ์…˜์€ ์™„์ „ํžˆ ์™„๋ฃŒ๋  ๋•Œ๊นŒ์ง€ ๋‹ค๋ฅธ ํŠธ๋žœ์žญ์…˜์—์„œ ์ˆ˜ํ–‰ ๊ฒฐ๊ณผ๋ฅผ ์ฐธ์กฐํ•  ์ˆ˜ ์—†๋‹ค.

Durablility(์˜์†์„ฑ,์ง€์†์„ฑ) - ํŠธ๋ž™์žญ์…˜์— ์˜ํ•ด ์ฒ˜๋ฆฌ๋œ ๋ฐ์ดํ„ฐ๋Š” ์˜๊ตฌ์ ์œผ๋กœ ์ €์žฅ๋œ๋‹ค.

  • ์„ฑ๊ณต์ ์œผ๋กœ ์™„๋ฃŒ๋œ ํŠธ๋žœ์žญ์…˜์˜ ๊ฒฐ๊ณผ๋Š” ์‹œ์Šคํ…œ์ด ๊ณ ์žฅ๋‚˜๋”๋ผ๋„ ์˜๊ตฌ์ ์œผ๋กœ ๋ฐ˜์˜๋˜์–ด์•ผ ํ•œ๋‹ค.

 

๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์—์„œ ์ผ์–ด๋‚˜๋Š” ๋ชจ๋“  ์ž‘์—…์€ ํŠธ๋žœ์žญ์…˜์ด ๊ฑธ๋ฆฐ๋‹ค.

ํ•˜์ง€๋งŒ ๋ชจ๋“  ์ž‘์—…์„ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ๋‹จ์—์„œ ์™„๋ฒฝํžˆ ACID ํ•˜๊ฒŒ ์ฒ˜๋ฆฌํ•˜๋ ค๋ฉด, ํ…Œ์ด๋ธ” ์ž ๊ธˆ์ด ๋„ˆ๋ฌด ๋งŽ์ด ๊ฑธ๋ ค ์„ฑ๋Šฅ์ด ์•ˆ์ข‹์•„์ง„๋‹ค.

๊ทธ๋ž˜์„œ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์—์„  ํŠธ๋žœ์žญ์…˜ ๊ฒฉ๋ฆฌ๋ ˆ๋ฒจ์ด ์กด์žฌํ•œ๋‹ค.

 

 

๐ŸŽฏ ํŠธ๋žœ์žญ์…˜ ๊ฒฉ๋ฆฌ๋ ˆ๋ฒจ?

ํŠธ๋žœ์žญ์…˜์—์„œ ์ผ๊ด€์„ฑ์ด ์—†๋Š” ๋ฐ์ดํ„ฐ๋ฅผ ํ—ˆ์šฉํ•˜๋Š” ์ˆ˜์ค€. ๊ตฌ์ฒด์ ์œผ๋กœ ๋งํ•˜์ž๋ฉด ๋™์‹œ์— ์—ฌ๋Ÿฌ ํŠธ๋žœ์žญ์…˜์ด ์ฒ˜๋ฆฌ ๋  ๋•Œ, A ํŠธ๋žœ์žญ์…˜์ด BํŠธ๋žœ์žญ์…˜์—์„œ [๋ณ€๊ฒฝ&์กฐํšŒํ•˜๋Š” ๋ฐ์ดํ„ฐ]๋ฅผ ์ฝ์„ ์ˆ˜ ์žˆ๋„๋ก ํ—ˆ์šฉํ• ์ง€ ๋ง์ง€๋ฅผ ๊ฒฐ์ •ํ•˜๋Š” ์ˆ˜์ค€์„ ์˜๋ฏธํ•œ๋‹ค.

  1. READ UNCOMMITTED (์ปค๋ฐ‹ ๋ฌด์‹œํ•˜๊ณ  ์ค‘๊ฐ„์— ๋ง‰ ์ฝ๊ธฐ)
  2. READ COMMITTED (์ปค๋ฐ‹๋œ ๋ฐ์ดํ„ฐ๋งŒ ์ฝ๊ธฐ)
  3. REPEATABLE READ (ํ•œ ํŠธ๋žœ์žญ์…˜์—์„œ ์—ฌ๋Ÿฌ๋ฒˆ ์ฝ์–ด๋„ ๋™์ผํ•จ ๋ณด์žฅ)
  4. SERIALIZABLE (์ˆœ์„œ๋Œ€๋กœ ์‹คํ–‰, ์ž‘์—…๋งˆ๋‹ค ์ „๋ถ€ ๋‹ค ๋ฐ์ดํ„ฐ ์ž ๊ธˆ)

ํŠธ๋žœ์žญ์…˜์€ ์›์ž์ ์ด๋ฉด์„œ ๋…๋ฆฝ์ ์ธ ์ˆ˜ํ–‰์„ ํ•ด์•ผํ•œ๋‹ค.(ACID) ๊ทธ๋ž˜์„œ ํŠธ๋žœ์žญ์…˜์ด DB๋ฅผ ๋‹ค๋ฃจ๋Š” ๋™์•ˆ, ๋‹ค๋ฅธ ํŠธ๋žœ์žญ์…˜์ด ๊ด€์—ฌ ๋ชปํ•˜๊ฒŒ Locking์„ ํ•ด์•ผํ•˜๋Š”๋ฐ, ๋ฌด์ž‘์ • ๋‹ค ์ž ๊ทธ๊ฒŒ๋˜๋ฉด DB์˜ ์„ฑ๋Šฅ์ด ํฌ๊ฒŒ ๋–จ์–ด์ง„๋‹ค. ์–ด๋””๊นŒ์ง€ ์ž ๊ธ€ ๊ฒƒ์ธ๊ฐ€ ์ •ํ•˜๋Š” ๊ฒƒ์ด ํŠธ๋žœ์žญ์…˜์˜ ๊ฒฉ๋ฆฌ์ˆ˜์ค€์ด๋‹ค.

 

๐ŸŽฏ (Lock) ์ž ๊ทผ๋‹ค๋Š” ๊ฒƒ์€?

์‚ฌ์šฉ์ค‘์ธ ๋ฐ์ดํ„ฐ๋ฅผ ์ฝ๊ฑฐ๋‚˜ ์กฐ์ž‘ํ•˜์ง€ ๋ชปํ•˜๊ฒŒ ๋ง‰๋Š”๋‹ค๋Š” ๊ฒƒ์ด๋‹ค.

  • ํ•œ ํ…Œ์ด๋ธ” ์ „์ฒด๋ฅผ ์ž ๊ธ€ ์ˆ˜ ์žˆ๋‹ค.
  • ํ…Œ์ด๋ธ”์˜ ํ•œ ํ–‰(row)๋ฅผ ์ž ๊ธ€ ์ˆ˜ ์žˆ๋‹ค.
    - Shared Lock : ์ฝ๊ธฐ์šฉ ์ž ๊ธˆ, ์ฝ๋Š” ๊ฑด ๊ฐ€๋Šฅํ•˜์ง€๋งŒ ๋ฐ์ดํ„ฐ๋ฅผ ์ˆ˜์ •ํ•˜์ง€ ๋ชปํ•˜๊ฒŒ ๋ง‰๋Š”๋‹ค.
    - Exclusive Lock : ์ƒํ˜ธ๋ฒ ํƒ€์ ์ธ ์ž ๊ธˆ, ์ฝ๊ณ  ์“ฐ์ง€ ๋ชปํ•˜๊ฒŒ ์™„์ „ํžˆ ๋ง‰๋Š”๋‹ค.
    ์ƒํ˜ธ๋ฒ ํƒ€์ ์ด๋ผ๋Š”๊ฑด, ๋‘˜ ์ค‘ ํ•˜๋‚˜๋งŒ ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•˜๋‹ค๋Š” ๋ง์ด๋‹ค.
  • ๊ทธ ์™ธ, ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋งˆ๋‹ค ์„ฑ๋Šฅ ํ–ฅ์ƒ์„ ์œ„ํ•œ ๋‹ค์–‘ํ•œ ํ˜•ํƒœ์˜ ์ž ๊ธˆ์ด ์กด์žฌํ•  ์ˆ˜ ์žˆ๋‹ค.

 

 

๐ŸŽฏ ์ž๋ฐ”์—์„œ DB๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•์€?

JDBC๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•๋งŒ ์กด์žฌํ•œ๋‹ค. (* ๋ฌผ๋ก  ์ €์ˆ˜์ค€์˜ TCP/IP ๋„คํŠธ์›Œํฌ ํ†ต์‹ ์„ ์ง์ ‘ ๊ตฌํ˜„ํ•˜๋Š” ๋ฐฉ๋ฒ•๋„ ์žˆ์ง€๋งŒ, ์ด๋Š” ์ œ์™ธํ•˜๊ณ )

// ์ฐธ๊ณ ๋กœ Java7 ์ดํ›„์—์„œ๋Š” ์ง์ ‘ close ํ•˜์ง€์•Š์•„๋„, try(..)๋ฅผ ์‚ฌ์šฉํ•ด AutoClosable์„ ์ด์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.
Connection conn = null;
PreparedStatement  pstmt = null;
ResultSet rs = null;

try {
    sql = "SELECT * FROM MEMBER"

    // 1. ๋“œ๋ผ์ด๋ฒ„ ์—ฐ๊ฒฐ DB ์ปค๋„ฅ์…˜ ๊ฐ์ฒด๋ฅผ ์–ป์Œ
    connection = DriverManager.getConnection(DBURL, DBUSER, DBPASSWORD);

    // 2. ์ฟผ๋ฆฌ ์ˆ˜ํ–‰์„ ์œ„ํ•œ Statement ๊ฐ์ฒด ์ƒ์„ฑ
    stmt = conn.createStatement();

    // 3. executeQuery: ์ฟผ๋ฆฌ ์‹คํ–‰ ํ›„
    // ResultSet: DB ๋ ˆ์ฝ”๋“œ ResultSet์— ๊ฐ์ฒด์— ๋‹ด๊น€
    rs = stmt.executeQuery(sql);
    } catch (Exception e) {
    } finally {
        conn.close();
        pstmt.close();
        rs.close();
    }
}

JDBC๊ฐ€ ์ž‘๋™๋˜๋Š” ๊ณผ์ •. DAO๋Š” ์‚ฌ์šฉ์ž๊ฐ€ ์ง์ ‘ ๋งŒ๋“  ์ฝ”๋“œ (DataAccessObject)

 

 

๐ŸŽฏ ์ž๋ฐ”์—์„œ ์–ด๋–ป๊ฒŒ ํŠธ๋žœ์žญ์…˜์ด ๊ฑธ๋ฆฌ๋Š”๊ฐ€?

๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋Š” ํŠธ๋žœ์žญ์…˜ ๋‹จ์œ„๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ๊ด€๋ฆฌํ•œ๋‹ค. Commit ๋˜์ง€ ์•Š์•˜๋Š”๋ฐ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ–ˆ๋‹ค๋ฉด, ํŠธ๋žœ์žญ์…˜ ์ž‘์—…์„ ํ†ต์œผ๋กœ ๋กค๋ฐฑ์‹œํ‚จ๋‹ค.

์ž๋ฐ”์—์„œ๋Š” JDBC์— ์—ฐ๊ฒฐ๋œ Connection์„ ์ด์šฉํ•˜์—ฌ ํŠธ๋žœ์žญ์…˜์„ ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ๋‹ค.

// ์ปค๋„ฅ์…˜ ํ’€์—์„œ DB์ปค๋„ฅ์…˜์„ ๋ฐ›์•„์™”๋‹ค๊ณ  ๊ฐ€์ •
Connection connection = dataSource.getConnection();

try (connection) {
    connection.setAutoCommit(false); // ์ž๋™ ์ปค๋ฐ‹ off
    // ...DB ์ž‘์—…...
    connection.commit(); // ์„ฑ๊ณต์‹œ ํŠธ๋žœ์žญ์…˜ ์ปค๋ฐ‹
} catch (SQLException e) {
    connection.rollback(); // ์˜ค๋ฅ˜ ๋ฐœ์ƒ์‹œ ํŠธ๋žœ์žญ์…˜ ๋กค๋ฐฑ
}

 

๊ธฐ๋ณธ์ ์œผ๋กœ ํŠธ๋žœ์žญ์…˜ ์ž๋™ ์ปค๋ฐ‹ ๋ชจ๋“œ์ธ๋ฐ, ์ด ๊ฒฝ์šฐ ๋ชจ๋“  SQL๋ฌธ์€ ๊ฐœ๋ณ„ ํŠธ๋žœ์žญ์…˜์œผ๋กœ ์‹คํ–‰๋˜๊ณ , ์ปค๋ฐ‹๋œ๋‹ค.
์ฐธ๊ณ ๋กœ ๋Œ€๋ถ€๋ถ„์˜ ์ปค๋„ฅ์…˜ ํ’€์€ JDBC์˜ AutoCommit์„ ๋„๊ณ  ์ง์ ‘ ํŠธ๋žœ์žญ์…˜์„ ๊ด€๋ฆฌํ•œ๋‹ค.

  • Insert, Update, Delete ์ž‘์—…์€ ์‹คํ–‰์ด ์™„๋ฃŒ ๋˜๋Š” ์ฆ‰์‹œ Commit ๋œ๋‹ค.
  • Select ์ž‘์—…์€ ์—ฐ๊ฒฐ๋œ ๊ฒฐ๊ณผ๊ฐ์ฒด(ResultSet)์ด ๋‹ซํžˆ๋ฉด Commit ๋œ๋‹ค.
  • connection.setReadOnly(true) ์ ์šฉํ•  ๊ฒฝ์šฐ, DB ๋“œ๋ผ์ด๋ฒ„์— ํžŒํŠธ๋ฅผ ์ œ๊ณตํ•œ๋‹ค. ๋‹จ ํŠธ๋žœ์žญ์…˜ ์‹คํ–‰ ๋„์ค‘์—๋Š” ์„ค์ •์„ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์—†๋‹ค.

์ž๋™ ์ปค๋ฐ‹๋ชจ๋“œ๊ฐ€ ์•„๋‹Œ ๊ฒฝ์šฐ, Commit ํ•˜๊ฑฐ๋‚˜ Rollback ํ•  ๋•Œ ์ž‘์—…์ด ์ข…๋ฃŒ๋œ๋‹ค.

์˜ค๋ผํด ๊ณต์‹๋ฌธ์„œ - setAutoCommit (Java17)

์ฐธ๊ณ ๋กœ Spring์™€ ํ•˜์ด๋ฒ„๋„ค์ดํŠธ์—์„œ ์ œ๊ณตํ•ด์ฃผ๋Š” @Transactional๋Š” ์•Œ์•„์„œ ํŠธ๋žœ์žญ์…˜์„ ๊ด€๋ฆฌํ•ด์ฃผ๋Š” ๋งˆ๋ฒ•์˜ ํ‚ค์›Œ๋“œ๊ฐ€ ์•„๋‹ˆ๋‹ค. ์ถ”์ƒํ™”ํ•ด์„œ ์‚ฌ์šฉํ•  ๋ฟ์ด์ง€ ์‹ค์ œ๋Š” ์œ„์˜ ์ฝ”๋“œ์ฒ˜๋Ÿผ JDBC ํŠธ๋žœ์žญ์…˜์„ ์‚ฌ์šฉํ•˜์—ฌ ๊ตฌํ˜„ํ•œ๋‹ค.

 

 

๐ŸŽฏ ์—ฌ๋Ÿฌ Select๋ฅผ ํ•˜๋‚˜์˜ ํŠธ๋žœ์žญ์…˜์œผ๋กœ ๋ฌถ์œผ๋ฉด ์–ด๋–ป๊ฒŒ ๋˜๋Š”๊ฐ€?

DB์˜ ๋™์‹œ์„ฑ ์ œ์–ด ๋ฉ”์ปค๋‹ˆ์ฆ˜์— ๋”ฐ๋ผ ๋‹ค๋ฅด๋‹ค. ๋‹ค๋งŒ ๋Œ€๋ถ€๋ถ„์˜ ๊ฒฝ์šฐ READ-COMMIT ๊ฒฉ๋ฆฌ ์ˆ˜์ค€์—์„œ ๋ฌถ๋Š” ๊ฒฝ์šฐ์—๋Š” ์ด์ ์€ ๋”ฐ๋กœ ์—†๋‹ค.
๋‹น์—ฐํžˆ REPEATABLE-READ ์˜ ๊ฒฝ์šฐ, ๋ฌถ๋Š” ๊ฒฝ์šฐ์™€ ๋ฌถ์ง€ ์•Š๋Š” ๊ฒฝ์šฐ ๋ฐ์ดํ„ฐ ๊ฒฐ๊ณผ๊ฐ€ ๋‹ค๋ฅผ ์ˆ˜ ์žˆ๋‹ค

๋ฐ˜๋Œ€๋กœ ๋„ˆ๋ฌด ๋งŽ์ด ๋ฌถ์–ด ํ•ด๋‹น ํŠธ๋žœ์žญ์…˜์ด ์žฅ๊ธฐ ์‹คํ–‰ ๋  ๊ฒฝ์šฐ, ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์„ฑ๋Šฅ์ด ์•ˆ ์ข‹์•„ ์งˆ ์ˆ˜ ์žˆ๋‹ค.

ํŠธ๋žœ์žญ์…˜์ด ์ข…๋ฃŒ ๋  ๋•Œ ๊นŒ์ง€ ํ…Œ์ด๋ธ”์˜ ์ผ๋ถ€๋ฅผ ์—…๋ฐ์ดํŠธ ํ•  ์ˆ˜ ์—†๊ธฐ๋•Œ๋ฌธ์ด๋‹ค. (์ด๋Š” Select๊ฐ€ ์•„๋‹Œ DDL, Index ๋ณ€๊ฒฝ์ž‘์—…๋„ ๋งˆ์ฐฌ๊ฐ€์ง€)

 

* ๋‹จ, ์„œ๋ฒ„(Java)์ž…์žฅ์—์„œ๋Š” Select๋ฅผ ์‹œ๋„ํ•  ๋•Œ๋งˆ๋‹ค DB Connection์„ ์ƒˆ๋กญ๊ฒŒ ์ƒ์„ฑํ•œ๋‹ค๋ฉด ์„œ๋ฒ„ ์„ฑ๋Šฅ์ด ๋‚˜๋น ์ง€๊ฒ ์ง€๋งŒ, ์ด๋Š” ์ปค๋„ฅ์…˜ ํ’€์„ ์‚ฌ์šฉํ•˜๋ฉด ํ•ด๊ฒฐ๋œ๋‹ค.

 

 

๐ŸŽฏ ์ปค๋„ฅ์…˜์„ ๋ฏธ๋ฆฌ ์—ด์–ด๋‘”๋‹ค๋Š” ๊ฒŒ ์ •ํ™•ํžˆ ๋ฌด์Šจ ์˜๋ฏธ์ธ๊ฐ€?

Java ์„œ๋ฒ„๋Š” JVM ์œ„์—์„œ ๋Œ์•„๊ฐ€๋Š” ํ”„๋กœ๊ทธ๋žจ์ด๊ณ , JVM์€ ์šด์˜์ฒด์ œ ์œ„์—์„œ ๋Œ์•„๊ฐ€๋Š” ํ”„๋กœ๊ทธ๋žจ, ์ •ํ™•ํžˆ๋Š” ํ”„๋กœ์„ธ์Šค์ด๋‹ค.

์„œ๋ฒ„(ํ”„๋กœ์„ธ์Šค)๊ฐ€ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค(ํ”„๋กœ์„ธ์Šค)์™€ ์—ฐ๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” TCP/IP๊ฐ€ ๊ตฌํ˜„๋œ ์šด์˜์ฒด์ œ๊ฐ€ ์ œ๊ณตํ•ด์ฃผ๋Š” ์†Œ์ผ“ ํ†ต์‹ ์„ ํ•ด์•ผํ•œ๋‹ค.

ํ”„๋กœ๊ทธ๋žจ์€ OS๊ฐ€ ์ œ๊ณตํ•˜๋Š” ์†Œ์ผ“ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ํ†ตํ•ด TCP/IP ํ†ต์‹ ์„ ํ•œ๋‹ค.

 

์†Œ์ผ“์€ 1982๋…„ BSD(Berkeley Software Distribution) ์œ ๋‹‰์Šค 4.1์—์„œ ์ฒ˜์Œ ์†Œ๊ฐœ๋˜์—ˆ์œผ๋ฉฐ ํ˜„์žฌ ์‚ฌ์šฉ์ค‘์ธ ์†Œ์ผ“์€ ์ •ํ™•ํžˆ 1986๋…„ BSD ์œ ๋‹‰์Šค4.3์—์„œ ๊ฐœ์ •๋œ ๊ธฐ๋Šฅ์ด๋‹ค. ์ดํ›„ TCP/IP ์˜ ํ‘œ์ค€์œผ๋กœ ์ฑ„ํƒ๋˜์—ˆ๋‹ค. 

์†Œ์ผ“์„ ์ƒ์„ฑํ•œ ํ›„, TCP/IP ๋ฅผ ์ด์šฉํ•ด ์—ฐ๊ฒฐ์„ ํ•œ๋‹ค. ๊ทธ ์ดํ›„ ๋ฐ์ดํ„ฐ๋ฅผ ์ „์†ก/์ˆ˜์‹ ์„ ๊ณ„์†ํ•˜๋‹ค๊ฐ€, ๋”์ด์ƒ ํ•„์š”์—†๋‹ค๋ฉด ์—ฐ๊ฒฐ์„ ๋Š๋Š”๋‹ค.

 

์šด์˜์ฒด์ œ๊ฐ€ ์ œ๊ณตํ•˜๋Š” Socket ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์ด์šฉํ•˜๊ธฐ ์œ„ํ•ด์„ , System Call ๋ช…๋ น์„ ์ด์šฉํ•˜์—ฌ ์ปค๋„ ๋ชจ๋“œ๋กœ ์ง„์ž…ํ•ด์•ผํ•œ๋‹ค.

๋”๋ณด๊ธฐ
์‹œ์Šคํ…œ์ฝœ์ด ๋ญ”์ง€ ๋ชจ๋ฅธ๋‹ค๋ฉด https://limjunho.github.io/2021/05/11/SystemCall.html

์–ด์…ˆ๋ธ”๋ฆฌ(๊ธฐ๊ณ„์–ด) ์—์„œ๋Š” ํ•„์š”ํ•œ ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ (๋ ˆ์ง€์Šคํ„ฐ ์ž์ฒด or ๋ ˆ์ง€์Šคํ„ฐ์— ํŠน์ • ๋ฉ”๋ชจ๋ฆฌ ์ฃผ์†Œ ๊ธฐ๋ก or ์Šคํƒ ๋ฉ”๋ชจ๋ฆฌ)์— ๋„ฃ์€ ํ›„
์ธํ„ฐ๋ŸฝํŠธ ๋ช…๋ น(INT), ์‹œ์Šคํ…œ์ ‘๊ทผ ๋ช…๋ น(SYSENTER), ๋˜๋Š” x64 ์ดํ›„ ์šด์˜์ฒด์ œ๋ผ๋ฉด SYSCALL ๋ช…๋ น์„ ์ด์šฉํ•˜์—ฌ ์‹œ์Šคํ…œ ์ฝœ์„ ํ•  ์ˆ˜ ์žˆ๋‹ค.

C์–ธ์–ด์—์„œ๋Š” ํŒŒ์ผ๋””์Šคํฌ๋ฆฝํ„ฐ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” API๋ฅผ ์ด์šฉํ•˜์—ฌ ์‹œ์Šคํ…œ ์ฝœ์„ ํ•  ์ˆ˜ ์žˆ๊ณ , ๊ทธ ๊ณผ์ •์€ ์•„๋ž˜์™€ ๊ฐ™๋‹ค.
C ํ”„๋กœ์„ธ์Šค -> ์‹œ์Šคํ…œ ์ฝœ -> ์ปค๋„ -> ๋””์Šคํฌ ์ปจํŠธ๋กค๋Ÿฌ -> ๋ฐ์ดํ„ฐ ๋ณต์‚ฌ

 

์ž๋ฐ”์—์„œ๋„ ํฌ๊ฒŒ ๋‹ค๋ฅด์ง€์•Š๋‹ค. ์•„๋ž˜์˜ ๊ณผ์ •์œผ๋กœ ์‹œ์Šคํ…œ ์ฝœ์ด ์ด๋ฃจ์–ด์ง„๋‹ค.
JVM -> JNI -> ์‹œ์Šคํ…œ ์ฝœ -> ์ปค๋„ -> ๋””์Šคํฌ ์ปจํŠธ๋กค๋Ÿฌ -> ์ปค๋„ ๋ฒ„ํผ ๋ณต์‚ฌ -> JVM ๋ฒ„ํผ ๋ณต์‚ฌ

 

์ฐธ๊ณ ๋กœ ํŒŒ์ผ ์ž…์ถœ๋ ฅ์ด๋‚˜ ๋„คํŠธ์›Œํฌ ์ž…์ถœ๋ ฅ์ด๋‚˜ ์šด์˜์ฒด์ œ ์ž…์žฅ์—์„œ๋Š” ๋™์ž‘์ด ํฌ๊ฒŒ ๋‹ค๋ฅด์ง€ ์•Š๋‹ค. I/O ๋ณ‘๋ชฉ๋˜๋Š” ๊ฒƒ๋„ ๋น„์Šทํ•˜๊ณ .

 

 

์ž๋ฐ”์—์„œ๋Š” ์ด๋Ÿฌํ•œ ์†Œ์ผ“ ํ†ต์‹ ์„ java.net.Socket, java.net.ServerSocket ์„ ์ด์šฉํ•˜์—ฌ ์ง์ ‘ ํ•  ์ˆ˜ ์žˆ๋‹ค.

baeldung.com - ์ž๋ฐ” ์†Œ์ผ“ ํ†ต์‹  ๊ฐ€์ด๋“œ

// ์„œ๋ฒ„ ์†Œ์ผ“์ƒ์„ฑ ํ›„, ์†Œ์ผ“์„ ์ด์šฉํ•œ ์ž๋ฐ” IO ์ŠคํŠธ๋ฆผ ์ƒ์„ฑ
Socket clientSocket = new Socket("127.0.0.1", 6666);
PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true); 

// (๋‹ค๋ฅธ ํ”„๋กœ๊ทธ๋žจ) ํด๋ผ์ด์–ธํŠธ ์†Œ์ผ“ ์ƒ์„ฑ ํ›„, ์†Œ์ผ“์„ ์ด์šฉํ•œ ์ž๋ฐ” IO ์ŠคํŠธ๋ฆผ ์ƒ์„ฑ
Socket clientSocket = serverSocket.accept();
BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));

 

์ด๊ฑธ๋กœ ์ง์ ‘ ํ†ต์‹ ์„ ํ•ด๋„ ๋˜์ง€๋งŒ, ๋‹คํ–‰ํžˆ java.sql ํŒจํ‚ค์ง€์—๋Š” ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์™€ ์†Œ์ผ“ ํ†ต์‹ ์„ ์‰ฝ๊ฒŒ ํ• ์ˆ˜ ์žˆ๊ฒŒ Connection ๊ฐ์ฒด๋ฅผ ์ œ๊ณตํ•œ๋‹ค.

์ž๋ฐ”์—์„œ .getConnection(..) ์€ ์ปค๋„ฅ์…˜ ๊ฐ์ฒด ๊ตฌํ˜„์„ ํ•ด๋‹น JDBC ๋“œ๋ผ์ด๋ฒ„๊ฐ€ ๊ตฌํ˜„ํ•˜๋„๋ก ๋งŒ๋“ค์–ด๋†จ๋‹ค. 

// DataSource ์ธํ„ฐํŽ˜์ด์Šค์˜ ๊ตฌํ˜„์ฒด์ธ JdbcRowSetImpl ์˜ ์ฝ”๋“œ
private static Connection getConnection(
       String url, java.util.Properties info, Class<?> caller) throws SQLException {
       /* ... ์ƒ๋žต ... */

       for (DriverInfo aDriver : registeredDrivers) {
           // If the caller does not have permission to load the driver then skip it.
           if (isDriverAllowed(aDriver.driver, callerCL)) {
               try {
                   println("    trying " + aDriver.driver.getClass().getName());
                   Connection con = aDriver.driver.connect(url, info);
                   if (con != null) {
                       // Success!
                       println("getConnection returning " + aDriver.driver.getClass().getName());
                       return (con);
                   }
               } catch (SQLException ex) {
                   if (reason == null) 
                       reason = ex;
               }

           } else 
               println("    skipping: " + aDriver.driver.getClass().getName());
       }

 

์ฆ‰ ์ปค๋„ฅ์…˜์„ ์—ด์–ด๋‘”๋‹ค๋Š” ๊ฑด, ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ํ†ต์‹ ์„ ์œ„ํ•œ ์†Œ์ผ“์„ ์—ด์–ด๋‘”๋‹ค๋Š” ์˜๋ฏธ๋‹ค.

 

 

๐ŸŽฏ ์ปค๋„ฅ์…˜์€ ๋‹ค๋‹ค์ต์„ ์ธ๊ฐ€?

  1. DB ์„œ๋ฒ„ ์ ‘์†์„ ์œ„ํ•ด JDBC ๋“œ๋ผ์ด๋ฒ„๋ฅผ ๋กœ๋“œํ•œ๋‹ค.
  2. DB ์ ‘์† ์ •๋ณด์™€ DriverManager.getConnection() Method๋ฅผ ํ†ตํ•ด DB Connection ๊ฐ์ฒด๋ฅผ ์–ป๋Š”๋‹ค.
  3. Connection ๊ฐ์ฒด๋กœ ๋ถ€ํ„ฐ ์ฟผ๋ฆฌ๋ฅผ ์ˆ˜ํ–‰ํ•˜๊ธฐ ์œ„ํ•œ PreparedStatement ๊ฐ์ฒด๋ฅผ ๋ฐ›๋Š”๋‹ค.
  4. executeQuery๋ฅผ ์ˆ˜ํ–‰ํ•˜์—ฌ ๊ทธ ๊ฒฐ๊ณผ๋กœ ResultSet ๊ฐ์ฒด๋ฅผ ๋ฐ›์•„์„œ ๋ฐ์ดํ„ฐ๋ฅผ ์ฒ˜๋ฆฌํ•œ๋‹ค.
  5. ์ฒ˜๋ฆฌ๊ฐ€ ์™„๋ฃŒ๋˜๋ฉด ์ฒ˜๋ฆฌ์— ์‚ฌ์šฉ๋œ ๋ฆฌ์†Œ์Šค๋“ค์„ closeํ•˜์—ฌ ๋ฐ˜ํ™˜ํ•œ๋‹ค.

์—ฌ๊ธฐ์—์„œ ๊ฐ€์žฅ ์‹œ๊ฐ„์ด ์˜ค๋ž˜๊ฑธ๋ฆฌ๋Š” ๋ถ€๋ถ„์€, DB์„œ๋ฒ„์™€ ์ตœ์ดˆ๋กœ ์†Œ์ผ“ ํ†ต์‹ ์„ ์—ฐ๊ฒฐ Connection ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜๋Š” ๋ถ€๋ถ„์ด๋‹ค.

๊ทธ๋ ‡๋‹ค๋ฉด ๋ฌด์ž‘์ • ์ปค๋„ฅ์…˜ ํ’€์˜ ํฌ๊ธฐ๋ฅผ ๋Š˜๋ฆฐ๋‹ค๋ฉด ์ข‹์„๊นŒ? ์•„๋‹ˆ. ๊ทธ๋ ‡์ง€์•Š๋‹ค.

 

๊ฒฐ๊ตญ ์ปค๋„ฅ์…˜์„ ์‚ฌ์šฉํ•˜๋Š”๊ฑด ์„œ๋ฒ„์— ๋Œ์•„๊ฐ€๊ณ  ์žˆ๋Š” Thead์ด๋‹ค.
Thread์˜ ๊ฐœ์ˆ˜๋ณด๋‹ค ์ปค๋„ฅ์…˜ ํ’€์˜ ํฌ๊ธฐ๊ฐ€ ํฌ๋‹ค๋ฉด ์‚ฌ์šฉํ•˜์ง€๋„ ์•Š๋Š” ์—ฌ์œ  ์ปค๋„ฅ์…˜๋งŒ ๋งŽ์ด ์ƒ๊ฒจ ๋ฉ”๋ชจ๋ฆฌ์˜ ๋‚ญ๋น„ ํ•˜๊ณ  ์žˆ์„ ๋ฟ์ด๋‹ค.

MySQL8.0 ๊ณต์‹๋ ˆํผ๋Ÿฐ์Šค์—์„œ๋Š” 600์—ฌ ๋ช…์˜ ์œ ์ €๋ฅผ ๋Œ€์‘ํ•˜๋Š”๋ฐ 15~20๊ฐœ์˜ ์ปค๋„ฅ์…˜ ํ’€๋งŒ์œผ๋กœ๋„ ์ถฉ๋ถ„ํ•˜๋‹ค๊ณ  ์–ธ๊ธ‰ํ•˜๊ณ  ์žˆ๋‹ค. MySQL์€ ์ตœ๋Œ€ ์—ฐ๊ฒฐ ์ˆ˜๋ฅผ ๋ฌด์ œํ•œ์œผ๋กœ ์„ค์ •ํ•œ ๋’ค ๋ถ€ํ•˜ ํ…Œ์ŠคํŠธ๋ฅผ ์ง„ํ–‰ํ•˜๋ฉด์„œ ์ตœ์ ํ™”๋œ ๊ฐ’์„ ์ฐพ๋Š” ๊ฒƒ์„ ์ถ”์ฒœํ•œ๋‹ค.

์‚ฌ์‹ค ์ด๋Ÿฐ ๊ฑด ์„œ๋ฒ„๋งˆ๋‹ค ์ตœ์ ์˜ ๊ฐ’์ด ๋‹ค๋ฅด๊ธดํ•˜๋‹ค. ๊ถ๊ธˆํ•˜๋‹ค๋ฉด ๋ฐฐ๋‹ฌ์˜๋ฏผ์กฑ  - HikariCP Dead lock์—์„œ ๋ฒ—์–ด๋‚˜๊ธฐ (์‹ค์ „ํŽธ) ๊ธ€์„ ์ฝ์–ด๋ณด์ž.

 

 

 

๐ŸŽฏ ์Šคํ”„๋ง ๋ฐ์ดํ„ฐ JPA์—์„œ, ์—ฌ๋Ÿฌ SELECT ๋ฌธ์„ ํ•˜๋‚˜๋กœ ๋ฌถ๋Š” ๊ฑด ์–ด๋–ค ์ฐจ์ด๊ฐ€ ์žˆ์„๊นŒ

@Transcational
void serviceMethod(){
    memberRepository.read()
    shopRepository.read()
    orderRepository.read()
}

@Transcational ํ‚ค์›Œ๋“œ๋Š” ํ•ด๋‹น ๋ฉ”์„œ๋“œ์˜ ์‹œ์ž‘, ๋์— PlatformTranscationManager๋ฅผ ํ”„๋ก์‹œ๋กœ ์‚ฝ์ž…ํ•œ๋‹ค.
๊ทธ๋ฆฌ๊ณ  .begin() .doCommit() ๊ฐ™์€ ๋ฉ”์„œ๋“œ๋ฅผ ์‹คํ–‰์‹œ์ผœ ํŠธ๋žœ์žญ์…˜์„ ๊ฑธ์–ด์ค€๋‹ค.

 

JPA์˜ ๊ฒฝ์šฐ์—๋Š” JpaTransactionManager ๊ฐ€ ๊ตฌํ˜„์ฒด๋กœ ์‚ฝ์ž…๋˜๋Š”๋ฐ, ์ฝ”๋“œ๋ฅผ ๋ณด๋ฉด ์•Œ๊ฒ ์ง€๋งŒ .doCommit()์€ ํŠธ๋žœ์žญ์…˜์„ ์ปค๋ฐ‹ํ•œ๋‹ค.

JpaTransactionManager.doCommit()

 

์ฐธ๊ณ ๋กœ ์šฐ๋ฆฌ๊ฐ€ ๋”ฐ๋กœ ํŠธ๋žœ์žญ์…˜์„ ๊ฑธ์ง€ ์•Š์•„๋„ ๊ธฐ๋ณธ ๊ตฌํ˜„์ฒด์ธ SimpleJpaRepository์—์„œ ํŠธ๋žœ์žญ์…˜์ด ๊ฑธ๋ ค์žˆ๋‹ค.

์ „์ฒด์— readOnly๋กœ ๊ฑธ์–ด๋‘๊ณ , ๋ฐ์ดํ„ฐ๋ฅผ ๋ณ€๊ฒฝํ•˜๋Š” ๋ฉ”์„œ๋“œ์—๋งŒ @Transcational(readOnly=false) ๊ฐ€ ๋”ฐ๋กœ ๋ถ™์–ด์žˆ๋‹ค.

 

 


@Transcational
void serviceMethod(){
    memberRepository.read()
    shopRepository.read()
    orderRepository.read()
}

๋‹ค์‹œ ๋ณธ๋ก ์œผ๋กœ ๋Œ์•„์™€์„œ, ์•„๋ž˜์™€ ๊ฐ™์ด ์กฐํšŒ๋ฉ”์„œ๋“œ์— @Transactional์„ ๊ฑธ๊ฒŒ๋˜๋ฉด
- ๊ทธ๋ƒฅ ์—ฌ๋Ÿฌ Select ๋“ค์„ ํ•œ ํŠธ๋žœ์žญ์…˜์— ๋„ฃ์–ด๋ฒ„๋ฆฐ๋‹ค.
- JPA๊ฐ€ ๋”ํ‹ฐ์ฒดํ‚น(์ˆ˜์ •๊ฐ์ง€)๋ฅผ ํ•œ๋‹ค.

DB์˜ ๋™์‹œ์„ฑ ์ œ์–ด ๋ฉ”์ปค๋‹ˆ์ฆ˜์— ๋”ฐ๋ผ ๋‹ค๋ฅด๋‹ค. ๋‹ค๋งŒ ๋Œ€๋ถ€๋ถ„์˜ ๊ฒฝ์šฐ READ-COMMIT ๊ฒฉ๋ฆฌ ์ˆ˜์ค€์—์„œ ๋ฌถ๋Š” ๊ฒฝ์šฐ์—๋Š” ์ด์ ์€ ๋”ฐ๋กœ ์—†๋‹ค.๋‹น์—ฐํžˆ REPEATABLE-READ ์˜ ๊ฒฝ์šฐ, ๋ฌถ๋Š” ๊ฒฝ์šฐ์™€ ๋ฌถ์ง€ ์•Š๋Š” ๊ฒฝ์šฐ ๋ฐ์ดํ„ฐ ๊ฒฐ๊ณผ๊ฐ€ ๋‹ค๋ฅผ ์ˆ˜ ์žˆ๋‹ค
๋ฐ˜๋Œ€๋กœ ๋„ˆ๋ฌด ๋งŽ์ด ๋ฌถ์–ด ํ•ด๋‹น ํŠธ๋žœ์žญ์…˜์ด ์žฅ๊ธฐ ์‹คํ–‰ ๋  ๊ฒฝ์šฐ, ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์„ฑ๋Šฅ์ด ์•ˆ ์ข‹์•„ ์งˆ ์ˆ˜ ์žˆ๋‹ค.
ํŠธ๋žœ์žญ์…˜์ด ์ข…๋ฃŒ ๋  ๋•Œ ๊นŒ์ง€ ํ…Œ์ด๋ธ”์˜ ์ผ๋ถ€๋ฅผ ์—…๋ฐ์ดํŠธ ํ•  ์ˆ˜ ์—†๊ธฐ๋•Œ๋ฌธ์ด๋‹ค. (์ด๋Š” Select๊ฐ€ ์•„๋‹Œ DDL, Index ๋ณ€๊ฒฝ์ž‘์—…๋„ ๋งˆ์ฐฌ๊ฐ€์ง€)

* ๋‹จ, ์„œ๋ฒ„(Java)์ž…์žฅ์—์„œ๋Š” Select๋ฅผ ์‹œ๋„ํ•  ๋•Œ๋งˆ๋‹ค DB Connection์„ ์ƒˆ๋กญ๊ฒŒ ์ƒ์„ฑํ•œ๋‹ค๋ฉด ์„œ๋ฒ„ ์„ฑ๋Šฅ์ด ๋‚˜๋น ์ง€๊ฒ ์ง€๋งŒ, ์ด๋Š” ์ปค๋„ฅ์…˜ ํ’€์„ ์‚ฌ์šฉํ•˜๋ฉด ํ•ด๊ฒฐ๋œ๋‹ค.

 

 

๊ทธ๋Ÿผ ์•„๋ž˜์™€ ๊ฐ™์ด readOnly=true๋กœ ๋ฌถ์–ด์ฃผ๋ฉด ์˜๋ฏธ์žˆ๋Š” ์ฐจ์ด๊ฐ€ ์žˆ์„๊นŒ?

@Transcational(readOnly=true)
void serviceMethod(){
    memberRepository.read()
    shopRepository.read()
    orderRepository.read()
}

์šฐ์„  JDBC ์—์„œ๋Š” readOnly ์— ๋Œ€ํ•œ ์ตœ์ ํ™”๋Š” JDBC Driver์—๊ฒŒ ์œ„์ž„ํ•  ๋ฟ, ์•„๋ฌด๋Ÿฐ ๋™์ž‘๋„ ํ•˜์ง€ ์•Š๋Š”๋‹ค.

์ฐธ๊ณ ๋กœ readOnly๋ผ๊ณ  ํ•ด์„œ ์ƒ์„ฑ,์‚ญ์ œ,์—…๋ฐ์ดํŠธ๋ฅผ ๋ง‰์•„์ฃผ๋Š” ๊ธฐ๋Šฅ์€ JDBC์—์„œ ์—†๋‹ค. ๊ทธ๋ƒฅ readOnly ํžŒํŠธ๋งŒ JDBC๋“œ๋ผ์ด๋ฒ„์—๊ฒŒ ์ค€๋‹ค.

 

ํ•˜์ง€๋งŒ JPA์˜ ๊ตฌํ˜„์ฒด์ธ ํ•˜์ด๋ฒ„๋„ค์ดํŠธ์—์„œ๋Š” ๋ช‡๊ฐ€์ง€ ์ตœ์ ํ™”๋ฅผ ํ•œ๋‹ค.

# (๋ฒˆ์™ธ) @Transcational(readOnly = true)์˜ ๋™์ž‘

- ๋ฉ”๋ชจ๋ฆฌ์— ์กด์žฌํ•˜๋Š” ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ๋ฅผ ํ”Œ๋Ÿฌ์‹œ ํ•˜์ง€ ์•Š๋Š”๋‹ค. entityManager.setFlushMode(MANUAL) ๋กœ ๊ฐ•์ œ๋กœ ๋ฐ”๊ฟ”๋ฒ„๋ฆฐ๋‹ค.

- ์ข€ ๋” ์‰ฝ๊ฒŒ๋งํ•˜๋ฉด ๋”ํ‹ฐ์ฒดํ‚น์„ ์•ˆํ•œ๋‹ค.

- ๊ทธ ์™ธ ์ฐจ์ด์ ์€, ์—ฐ๊ด€๊ด€๊ณ„๊ฐ€ LAZY๋กœ ๊ฑธ๋ ค์žˆ๋‹ค๋ฉด ํ•ด๋‹น ํŠธ๋žœ์žญ์…˜ ๋‚ด๋ถ€์—์„œ๋Š” ์ง€์—ฐ๋กœ๋”ฉ์„ ํ•œ๋‹ค๋Š”๊ฑฐ ์ •๋„๊ฐ€ ์žˆ๊ฒ ๋‹ค.

 

* ์ฐธ๊ณ ๋กœ ๋”ํ‹ฐ์ฒดํ‚น๊ณผ flush๋ฅผ ์•ˆํ•œ๋‹ค๊ณ  ํ–ˆ์ง€, ํŠธ๋žœ์žญ์…˜์˜ readOnly๊ฐ€ ์ˆ˜์ •/์‚ญ์ œ๋ฅผ ๋ง‰๋Š” ๊ธฐ๋Šฅ์ด ์žˆ์ง€๋Š” ์•Š๋‹ค.
save()๋ฅผ ์‹คํ–‰ํ•ด๋„ ์ž˜ ๋™์ž‘ํ•˜๊ณ , updated์˜ ๊ฒฝ์šฐ์—๋„ ์ง์ ‘ flush ์‹œ์ผœ์ฃผ๋ฉด ์‹ค์ œ DB์— ์ฟผ๋ฆฌ๊ฐ€ ์ฐํžŒ๋‹ค.

 

 

์ฆ‰ ์š”์•ฝํ•˜๋ฉด ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ๊ฒฉ๋ฆฌ ์ˆ˜์ค€์ด Read Commit ์ธ ๊ฒฝ์šฐ ์•„๋ฌด๋Ÿฐ ์ฐจ์ด๊ฐ€ ์—†๋‹ค.
๊ตณ์ด ๋”ฐ์ง€์ž๋ฉด ํ•œ ํŠธ๋žœ์žญ์…˜์ด ๊ธธ์–ด์ง = ์—ฌ๋Ÿฌ ๋ฐ์ดํ„ฐ์— SharedLock์ด ๊ฑธ๋ ค์„œ ์„ฑ๋Šฅ์ด ๋Š๋ ค์งˆ ์ˆ˜ ์žˆ๋‹ค.

Repeatable read ์˜ ๊ฒฝ์šฐ, ํŠธ๋žœ์žญ์…˜์„ ๊ฑด ๊ฒƒ๊ณผ ์•ˆ๊ฑด ๊ฒƒ์ด ๋ฐ์ดํ„ฐ ์ž ๊ธˆ ๋ฒ”์œ„์™€ ๋ฐ˜ํ™˜๊ฐ’์ด ๋‹ค๋ฅผ ์ˆ˜ ์žˆ๊ธฐ์— ์ด๋Š” ๋…ผ์™ธ๋กœ ํ•˜์ž.

๋ธ”๋กœ๊ทธ์˜ ์ •๋ณด

JiwonDev

JiwonDev

ํ™œ๋™ํ•˜๊ธฐ