Database/SQL

๋‚™๊ด€์  ๋™์‹œ์„ฑ ์ œ์–ด๋ฅผ ์ ์šฉํ•˜๋ฉด์„œ ๋งˆ์ฃผ์นœ ๋ฌธ์ œ: ํƒ€์ž„์Šคํƒฌํ”„

์ฑ”๐Ÿป 2024. 2. 11. 12:24

โœ”๏ธย ๊ฒฐ๋ก 

๐Ÿ‘€ย ๋ฌธ์ œ ์ •์˜

์ฒ˜์Œ์— ๋™์‹œ์„ฑ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๋ ค๊ณ  ํ•˜์˜€์„ ๋•Œ, ์ฒ˜์Œ์— ๊ฐ€์ •์„ Isolation Level์ด Repeatable Read๋กœ ํ•˜๋ฉด ์•ˆ ๋œ๋‹ค๋Š” ์ž˜๋ชป๋œ ๊ฐœ๋…์„ ๊ฐ€์ง€๊ณ  ์žˆ์—ˆ์–ด์„œ Read Committed๋กœ ๋‚ด๋ ค์•ผ ๋˜๋Š” ์ค„ ์•Œ๊ณ  ์–˜๋ฅผ ์œ„ํ•ด Read Committed๋กœ ๋‚ด๋ฆฌ๋Š” ๊ฑด ๋ง์ด ์•ˆ ๋˜๋Š” ๊ฒƒ ๊ฐ™์•„ ๋น„๊ด€์  ๋™์‹œ์„ฑ ์ œ์–ด๋กœ ํ•ด๊ฒฐํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์„ ํƒํ•˜์˜€๋Š”๋ฐ ใ…Ž,,

์ž˜๋ชป๋œ ์ง€์‹์œผ๋กœ ์ž˜๋ชป๋œ ํŒ๋‹จ์„ ๋‚ด๋ฆฌ๊ณ  ์žˆ์—ˆ๋‹ค ใ… ใ… ใ… 

JPA๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค๋ฉด Version์œผ๋กœ ๊น”๋”ํ•˜๊ฒŒ ๊ตฌํ˜„์ด ๊ฐ€๋Šฅํ•˜๋˜๋ฐ,

๋‚˜๋Š” Spring + MyBatis์—ฌ์„œ ์ฟผ๋ฆฌ๋ฌธ์—์„œ CAS(compare-and-set) ๋ฐฉ์‹์œผ๋กœ ๋‚™๊ด€์  ๋™์‹œ์„ฑ ์ œ์–ด ๋ฐฉ๋ฒ•์„ ๊ตฌํ˜„ํ•˜๋Š” ๊ฒƒ์„ ์‚ฌ์šฉํ•˜์˜€๋‹ค.

์œ„์—์„œ ๋งํ•œ ์ž˜๋ชป๋œ ์ง€์‹์„ ๊ฐ€์ง€๊ณ  ์ผ๋‹จ ๋‚™๊ด€์  ๋™์‹œ์„ฑ ์ œ์–ด๋ฅผ ์ ์šฉํ•ด๋ณด์•˜๋‹ค

  1. Isolation Level์„ MySQL์˜ ๊ธฐ๋ณธ์ธ Repeatable Read โ†’ Read Committed๋กœ ๋ณ€๊ฒฝ
    @Transactional(rollbackFor = Exception.class, isolation = Isolation.READ_COMMITTED)
    public void order(Order order) throws Exception {
        // 0-1. ์žฌ๊ณ ์ˆ˜๋Ÿ‰ ๊ฐ์†Œ
        decreaseProdQty(order.getOrdDtlList());
  1. ์žฌ๊ณ ์ˆ˜๋Ÿ‰ ๊ฐ์†Œ ์ฟผ๋ฆฌ์— UPD_DTTM(๋ณ€๊ฒฝ์ผ์‹œ)์ด ๋งˆ์ง€๋ง‰์œผ๋กœ ์ฝ์€ ํ›„๋กœ ๋ณ€๊ฒฝ๋˜์ง€ ์•Š์•˜์„ ๋•Œ๋งŒ ์ˆ˜์ •๋˜๋„๋ก ์ฟผ๋ฆฌ ์ˆ˜์ •
    <update id="decreaseProdQty" parameterType="Map">
        UPDATE prod_opt
        SET INV_QTY = INV_QTY - #{qty}
          , UPD_DTTM = now()
        WHERE OPT_COMB_NO = #{optCombNo}
        AND UPD_DTTM = #{updDttm}
    </update>

โ‡’ ์ด๋ ‡๊ฒŒ ์ˆ˜์ •ํ•œ ํ›„ ์žฌ๊ณ ๊ฐ€ 1๊ฐœ ๋‚จ์€ ์ƒํ’ˆ์„ 2๊ฐœ์˜ ์“ฐ๋ ˆ๋“œ๊ฐ€ ๋™์‹œ์— ์ฃผ๋ฌธํ•˜๋„๋ก ํ•˜๊ณ  ๋Œ๋ ค๋ณด์•˜๋Š”๋ฐ ๋‚ด๊ฐ€ ๊ธฐ๋Œ€ํ•œ ๊ฒฐ๊ณผ๊ฐ€ ์•„๋‹Œ ์žฌ๊ณ ์ˆ˜๋Ÿ‰์ด ์—ฌ์ „์ด -1์ด ๋จ

โ“ย ๋ถ„์„&์‹œ๋„

์‹œ๋„1) ์•ˆ ๋˜๋Š” ์ด์œ ๋ฅผ ๋‚˜๋ฆ„ ๋ถ„์„ํ•ด๋ณด์•˜๋‹ค

์•„๋ž˜๋Š” ๋‚ด๊ฐ€ ์ƒ๊ฐํ•œ ์œ„์˜ ์ƒํ™ฉ์˜ flow์˜€๋‹ค..

๊ทธ๋Ÿฌ๋‹ˆ๊นŒ ๊ฒฐ๋ก ์€ ํŠธ๋žœ์žญ์…˜1์—์„œ ์žฌ๊ณ ์ˆ˜๋Ÿ‰์„ ๋ณ€๊ฒฝํ•ด UPD_DTTM๋„ ์ตœ์‹ ๊ฐ’์œผ๋กœ ๋ณ€๊ฒฝ๋˜์—ˆ์œผ๋‚˜
Isolation Level์ด Read Committed๊ณ  ํŠธ๋žœ์žญ์…˜์ด ๋๋‚˜์ง€ ์•Š์•„ ์ปค๋ฐ‹์ด ๋˜์ง€ ์•Š์•˜๊ธฐ ๋•Œ๋ฌธ์— UPD_DTTM๋Š” ์—ฌ์ „ํžˆ ํŠธ๋žœ์žญ์…˜ ์‹œ์ž‘ ์‹œ ์ฝ์–ด์˜จ ๊ฐ’์ด๋‹ค.
๋”ฐ๋ผ์„œ UPD_DTTM ์ปฌ๋Ÿผ์„ ๋น„๊ตํ•˜๋Š” ๊ฒ€์ฆ ๋ถ€๋ถ„์ด ํ†ต๊ณผ๋˜์–ด ์žฌ๊ณ ์ˆ˜๋Ÿ‰์ด ๊ฐ์†Œ๋œ๋‹ค.

์‹œ๊ฐ„ ์ˆœ์„œํŠธ๋žœ์žญ์…˜ 1 ์ƒํƒœํŠธ๋žœ์žญ์…˜ 2 ์ƒํƒœ์„ค๋ช…
1Read: ์žฌ๊ณ ์ˆ˜๋Ÿ‰ & ๋ณ€๊ฒฝ์ผ์‹œ
์žฌ๊ณ ์ˆ˜๋Ÿ‰: 1๊ฐœ
๋ณ€๊ฒฝ์ผ์‹œ: 02/05/2024 10:02:18.000
2์žฌ๊ณ ์ˆ˜๋Ÿ‰ ๊ฒ€์ฆ: 1๊ฐœ ์ด์ƒ์ด๊ธฐ ๋•Œ๋ฌธ์— ํ†ต๊ณผRead: ์žฌ๊ณ ์ˆ˜๋Ÿ‰ & ๋ณ€๊ฒฝ์ผ์‹œ
์žฌ๊ณ ์ˆ˜๋Ÿ‰: 1๊ฐœ
๋ณ€๊ฒฝ์ผ์‹œ: 02/05/2024 10:02:18.000
1decreaseProdQty๋ฅผ ์‹คํ–‰ํ•ด ์žฌ๊ณ ์ˆ˜๋Ÿ‰์„ ๊ฐ์†Œ์‹œํ‚จ๋‹ค.
์ด๋•Œ ํŠธ๋žœ์žญ์…˜1์ด ์‹œ์ž‘๋œ ์ดํ›„๋กœ ์žฌ๊ณ ์ˆ˜๋Ÿ‰์ด ๋ณ€๊ฒฝ๋˜์ง€ ์•Š์•˜๊ธฐ ๋•Œ๋ฌธ์—
UPD_DTTM ์ปฌ๋Ÿผ์„ ๋น„๊ตํ•˜๋Š” ๊ฒ€์ฆ ๋ถ€๋ถ„์ด ํ†ต๊ณผ๋˜์–ด ์žฌ๊ณ ์ˆ˜๋Ÿ‰์ด ๊ฐ์†Œ๋œ๋‹ค.
์žฌ๊ณ ์ˆ˜๋Ÿ‰ ๊ฒ€์ฆ: 1๊ฐœ ์ด์ƒ์ด๊ธฐ ๋•Œ๋ฌธ์— ํ†ต๊ณผ
2๊ทธ ๋’ค๋กœ ์ฃผ๋ฌธ ๋กœ์ง ์ƒ์„ฑdecreaseProdQty๋ฅผ ์‹คํ–‰ํ•ด ์žฌ๊ณ ์ˆ˜๋Ÿ‰์„ ๊ฐ์†Œ์‹œํ‚จ๋‹ค.
ํŠธ๋žœ์žญ์…˜1์—์„œ ์žฌ๊ณ ์ˆ˜๋Ÿ‰์„ ๋ณ€๊ฒฝํ•ด UPD_DTTM๋„ ์ตœ์‹ ๊ฐ’์œผ๋กœ ๋ณ€๊ฒฝ๋˜์—ˆ์œผ๋‚˜
Isolation Level์ด Read Committed๊ณ  ํŠธ๋žœ์žญ์…˜์ด ๋๋‚˜์ง€ ์•Š์•„ ์ปค๋ฐ‹์ด ๋˜์ง€ ์•Š์•˜๊ธฐ ๋•Œ๋ฌธ์— UPD_DTTM๋Š” ์—ฌ์ „ํžˆ ํŠธ๋žœ์žญ์…˜ ์‹œ์ž‘ ์‹œ ์ฝ์–ด์˜จ ๊ฐ’์ด๋‹ค.
๋”ฐ๋ผ์„œ UPD_DTTM ์ปฌ๋Ÿผ์„ ๋น„๊ตํ•˜๋Š” ๊ฒ€์ฆ ๋ถ€๋ถ„์ด ํ†ต๊ณผ๋˜์–ด ์žฌ๊ณ ์ˆ˜๋Ÿ‰์ด ๊ฐ์†Œ๋œ๋‹ค.
3์ปค๋ฐ‹๊ทธ ๋’ค๋กœ ์ฃผ๋ฌธ ๋กœ์ง ์ƒ์„ฑ
4๊ฒฐ๊ณผ๋Š” ์žฌ๊ณ ์ˆ˜๋Ÿ‰ 0์ปค๋ฐ‹
5๊ฒฐ๊ณผ๋Š” ์žฌ๊ณ ์ˆ˜๋Ÿ‰ -1

์‹œ๋„2)

์œ„์—์„œ ์ •์˜ํ–ˆ๋˜ ์ด์ƒํ•œ ๊ฐ€์ •์œผ๋กœ ๋‚™๊ด€์  ๋™์‹œ์„ฑ ์ œ์–ด๋ฅผ ์ ์šฉํ•˜๋Š” ๊ณผ์ •์—์„œ ๊ต‰์žฅํžˆ ์‚ฝ์งˆ์„ ํ•˜๊ณ  ์žˆ์—ˆ๋‹ค.

์ผ๋ฐ˜์ ์œผ๋กœ ๋™์‹œ์„ฑ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๋Š” ๋ฐฉ๋ฒ•์€ ํฌ๊ฒŒ ๋‘ ๊ฐ€์ง€๋‹ค.

  1. ๋น„๊ด€์  ๋™์‹œ์„ฑ ์ œ์–ด(Pessimistic Concurrency Control)
  1. ๋‚™๊ด€์  ๋™์‹œ์„ฑ ์ œ์–ด(Optimistic Concurrency Control)

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

๊ตฌ๊ธ€๋ง์„ ํ†ตํ•ด ๋‹ค์–‘ํ•œ ํ•ด๊ฒฐ์ฑ…์„ ์ฐพ์•„๋ดค์ง€๋งŒ, ๋Œ€๋ถ€๋ถ„ JPA์˜ @Version์œผ๋กœ ํ•ด๊ฒฐํ•˜๊ณ  ์žˆ์—ˆ๊ณ  MyBatis ์‚ฌ์šฉ ์‚ฌ๋ก€๋Š” ์ฐพ๊ธฐ ์–ด๋ ค์› ๋‹ค. ๊ทธ๋Ÿฌ๋‹ค ์ฐพ๋‹ค์ฐพ๋‹ค ๋“œ๋””์–ด ์šฐ์—ฐํžˆ ํ•œ ๋ธ”๋กœ๊ทธ์—์„œ JPA๊ฐ€ ์•„๋‹ˆ๋ผ ๋‚ด๊ฐ€ ์ฑ…์—์„œ ๋ณธ ์ฟผ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•ด ๋™์‹œ์„ฑ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•œ ๊ธ€์„ ๋ฐœ๊ฒฌํ•˜๊ฒŒ๋˜์—ˆ๋‹ค..!

[DB] ๋™์‹œ์„ฑ ๋ฌธ์ œ ํ•ด๊ฒฐ๋ฐฉ๋ฒ•
๋™์‹œ์„ฑ ๋ฌธ์ œ๊ฐ€ ๋ฌด์—‡์ด๊ณ  ํ•ด๊ฒฐ๋ฐฉ๋ฒ•์— ๋Œ€ํ•˜์—ฌ ์•Œ์•„๋ณด๋„๋ก ํ•œ๋‹ค.
https://chrisjune-13837.medium.com/db-๋™์‹œ์„ฑ-๋ฌธ์ œ-ํ•ด๊ฒฐ๋ฐฉ๋ฒ•-f5e52e2e3

๋‚˜๋Š” ์ด๋ฏธ ์ž˜๋ชป๋œ ๊ฐ€์ •์— ๊นŠ์ด ๋น ์ ธ ์žˆ์–ด์„œ "์ € ๋ฐฉ๋ฒ•์œผ๋กœ ํ•ด๊ฒฐ๋  ๋ฆฌ๊ฐ€ ์—†๋‹ค"๊ณ  ์ƒ๊ฐํ•˜๋ฉฐ ๋ฐ˜์‹ ๋ฐ˜์˜ํ•˜๋ฉฐ ์†๋Š”์…ˆ์น˜๊ณ  ์‹œ๋„๋ฅผ ํ•ด๋ณด์•˜๋‹ค.

์žฌ๊ณ ์ˆ˜๋Ÿ‰ ๊ฐ์†Œ์ฟผ๋ฆฌ์— INV_QTY >= #{qty} ์กฐ๊ฑด์„ ์ถ”๊ฐ€ํ•ด ์‹ค์ œ ์žฌ๊ณ  ์ˆ˜๋Ÿ‰์ด ์ถฉ๋ถ„ํ•  ๋•Œ๋งŒ ์—…๋ฐ์ดํŠธํ•˜๋„๋ก ํ–ˆ๋‹ค. ๋ณ€๊ฒฝ ํ›„ ๊ฒฉ๋ฆฌ ์ˆ˜์ค€์— ์ƒ๊ด€์—†์ด Repeatable Read์™€ Read Committed ๋ชจ๋‘ ๋ฌธ์ œ์—†์ด ์ž‘๋™ํ•˜๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์—ˆ๋‹ค. ์ด ๊ฒฐ๊ณผ๋Š” ๋‚ด๊ฐ€ ์„ธ์šด ๊ฐ€์ •๊ณผ ์ „ํ˜€ ๋‹ฌ๋ž๊ณ .. ์˜ˆ์ƒ์น˜ ๋ชปํ•œ ๊ฒฐ๊ณผ์˜€๋‹ค. ๋‚ด ์˜ˆ์ƒ์œผ๋กœ๋Š” -1๋กœ ๋™์‹œ์„ฑ ๋ฌธ์ œ๊ฐ€ ํ•ด๊ฒฐ์ด ์•ˆ ๋˜์—ˆ์–ด์•ผ ํ–ˆ๋Š”๋ฐ ์‹ค์ œ๋กœ๋Š” 0์œผ๋กœ ๋™์‹œ์„ฑ ๋ฌธ์ œ๊ฐ€ ํ•ด๊ฒฐ๋˜์—ˆ๋‹ค..

๊ธฐ์กด

<update id="decreaseProdQty" parameterType="Map">
    UPDATE prod_opt
    SET INV_QTY = INV_QTY - #{qty}
      , UPD_DTTM = now()
    WHERE OPT_COMB_NO = #{optCombNo}
    AND UPD_DTTM = #{updDttm}
</update>

๋ณ€๊ฒฝ

<update id="decreaseProdQty" parameterType="Map">
    UPDATE prod_opt
    SET INV_QTY = INV_QTY - #{qty}
      , UPD_DTTM = now()
    WHERE OPT_COMB_NO = #{optCombNo}
    AND INV_QTY >= #{qty}
</update>

๊ทธ ์ด์œ ์— ๋Œ€ํ•ด์„œ๋Š” ์•„๋ž˜ ๊ธ€ ์ฐธ๊ณ .

๋‚™๊ด€์  ๋™์‹œ์„ฑ ์ œ์–ด๋ฅผ ์ ์šฉํ•˜๋ฉด์„œ ๋งˆ์ฃผ์นœ ๋ฌธ์ œ๋“ค: ์žฌ๊ณ ์ˆ˜๋Ÿ‰ ๋น„๊ต
๐Ÿ‘€ ์˜๋ฌธ์ โ“ ์›์ธ ์ถ”๋ก  & ์‹œ๋„1) ์ผ๋‹จ Repeatable Read๋กœ ์‹œ๋‚˜๋ฆฌ์˜ค ์งœ๋ณด๊ณ  ํ…Œ์ŠคํŠธ2) ์ฑ…, ์ž๋ฃŒ ์ฐพ์•„๋ณด๊ธฐ3) ํ—ท๊ฐˆ๋ ธ๋˜ ๋ถ€๋ถ„2๐Ÿ”œ ๋‚˜๊ฐ€๋ฉฐ๋” ์•Œ์•„๋ณผ ๊ฒƒRef ์•„๋ž˜๋Š” ์ œ ์‚ฝ์งˆ ๊ณผ์ •์„ ๊ธฐ๋กํ•œ ๊ธ€์ด๊ณ  ํ‹€๋ฆฐ ๋‚ด์šฉ์ด ํฌํ•จ๋˜์–ด์žˆ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹คโ€ฆ! ๐Ÿ‘€ ์˜๋ฌธ์ ์œ„ ๊ฒŒ์‹œ๊ธ€์—์„œ ์ •์˜ํ–ˆ๋˜ ์ด์ƒํ•œ ๊ฐ€์ •์œผ๋กœ ๋‚™๊ด€์  ๋™์‹œ์„ฑ ์ œ์–ด๋ฅผ ์ ์šฉํ•˜๋Š” ๊ณผ์ •์—์„œ ๊ต‰์žฅํžˆ ์‚ฝ์งˆ์„ ํ•˜๊ณ  ์žˆ์—ˆ๋‹ค.์ผ๋ฐ˜์ ์œผ๋กœ ๋™์‹œ์„ฑ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๋Š” ๋ฐฉ๋ฒ•์€ ํฌ๊ฒŒ ๋‘ ๊ฐ€์ง€๋‹ค.๋น„๊ด€์  ๋™์‹œ์„ฑ ์ œ์–ด(Pessimistic Concurrency Control)๋‚™๊ด€์  ๋™์‹œ์„ฑ ์ œ์–ด(Optimistic Concurrency Control) ์—ฌ๋Ÿฌ ์ฑ…์—์„œ๋Š” ๋‚™๊ด€์  ๋™์‹œ์„ฑ ์ œ์–ด๋ฅผ ํƒ€์ž„์Šคํƒฌํ”„๋ฅผ ํ™œ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•์œผ๋กœ ์†Œ๊ฐœํ•˜๊ณ  ์žˆ์—ˆ๋‹ค. ํ•˜์ง€๋งŒ ์‹ค์ œ๋กœ ์ ์šฉํ•ด ๋ณด์•˜๋Š”๋ฐ ๋™์‹œ์„ฑ ๋ฌธ์ œ๊ฐ€ ํ•ด๊ฒฐ๋˜์ง€ ์•Š์•˜๊ณ ..
https://beppp.tistory.com/126

3) ์ž˜๋ชป๋œ ๊ฐœ๋… ๋ฐ”๋กœ์žก์€ ํ›„, ํƒ€์ž„์Šคํƒฌํ”„๋กœ ์•ˆ ๋˜๋Š” ์ด์œ  ๋ถ„์„

์œ„ ๊ธ€์„ ํ†ตํ•ด์ž˜๋ชป๋œ ๊ฐœ๋… ๋ฐ”๋กœ์žก๊ณ , ๊ทธ๋ž˜์„œ ์™ผ์ชฝ์ด๋‚˜ ์˜ค๋ฅธ์ชฝ์ด๋‚˜ ๊ฐ™์€ ๋ฉ”์ปค๋‹ˆ์ฆ˜์ธ๋ฐ.. ์•ˆ ๋˜๋Š” ์ด์œ ๋ฅผ ๋ถ„์„ํ•ด๋ณด์•˜๋‹ค.

์ฒ˜์Œ ์ˆ˜์ •์ผ์‹œ๋ฅผ ์กฐํšŒํ•ด์˜จ ๊ฐ’์„ ์ฐ์–ด๋ณด์•˜๋Š”๋ฐ,

thread2

Executing order # on thread: ์žฌ๊ณ ์ˆ˜๋Ÿ‰ ๊ฐ์†Œ ํ›„ ์ˆ˜์ •์ผ์‹œ ํ™•์ธ์šฉpool-1-thread-2prodQtyList2: [ProdOptDTO{optItemNm='null', optCombNo=1, optPrc=0, invQty=0, prodId=10001, shoesSize='null', regDttm=null, regrId=0, updDttm=Mon Feb 05 18:39:56 KST 2024, updrId=0, delDttm=null, delrId=0, delYn='null'}]

thread1

Executing order # on thread: ์žฌ๊ณ ์ˆ˜๋Ÿ‰ ๊ฐ์†Œ ํ›„ ์ˆ˜์ •์ผ์‹œ ํ™•์ธ์šฉpool-1-thread-1prodQtyList2: [ProdOptDTO{optItemNm='null', optCombNo=1, optPrc=0, invQty=-1, prodId=10001, shoesSize='null', regDttm=null, regrId=0, updDttm=Mon Feb 05 18:39:56 KST 2024, updrId=0, delDttm=null, delrId=0, delYn='null'}]

updDttm์ด ์‹œ๋ถ„โ€™์ดˆโ€™๊นŒ์ง€๋งŒ ๊ฐ’์„ ๊ฐ€์ ธ์˜จ ๊ฑฐ ๋ณด๊ณ  ํ˜น์‹œ ํŠธ๋žœ์žญ์…˜์ด ๋„ˆ๋ฌด ๋น ๋ฅด๊ฒŒ ์ง„ํ–‰๋˜์–ด์„œ ๊ทธ๋Ÿฐ๊ฐ€..? ๋ผ๋Š” ์ƒ๊ฐ์ด ๋ฒˆ๋œฉ ๋“ค์—ˆ๋‹ค.

๊ฒฐ๋ก ์€ ์ด๊ฒŒ ๋งž์•˜๋‹ค..!

๋ชจ๋“  ๋กœ์ง์ด ์ „๋ถ€ 56์ดˆ ๋‚ด์— ์ˆ˜ํ–‰๋˜์–ด

ํŠธ๋žœ์žญ์…˜1์ด ๊ฐ’์„ ๋ณ€๊ฒฝํ•œ ํ›„ now()๋กœ updDttm์„ ์ˆ˜์ •ํ–ˆ์ง€๋งŒ ์ฒ˜์Œ ์กฐํšŒํ•ด์˜จ ๊ฐ’๊ณผ ๊ฐ™์€ 18:39:56์ด ์ €์žฅ๋˜์–ด์„œ ํŠธ๋žœ์žญ์…˜2๊ฐ€ ๋ณ€ํ™”๋ฅผ ๊ฐ์ง€ํ•˜์ง€ ๋ชปํ•ด ๋งˆ์ง€๋ง‰ ์ฝ์€ ํ›„๋กœ ๋ณ€๊ฒฝ๋˜์ง€ ์•Š์•˜๋‹ค๊ณ  ํŒ๋‹จํ•ด ์žฌ๊ณ ์ˆ˜๋Ÿ‰์„ ๋˜ ์ฐจ๊ฐํ•ด -1์ด ๋œ๊ฒƒ..

์žฌ๊ณ ๊ฐ€ 1๊ฐœ ๋‚จ์€ ์ƒํ’ˆ์„ 2๊ฐœ์˜ ์“ฐ๋ ˆ๋“œ๊ฐ€ ๋™์‹œ์— ์ฃผ๋ฌธ

  1. ์ฒ˜์Œ์— ์žฌ๊ณ ์ˆ˜๋Ÿ‰์„ ์กฐํšŒํ•ด์˜ฌ ๋•Œ ๋ณ€๊ฒฝ์ผ์‹œ๋„ ์กฐํšŒํ•ด์˜จ๋‹ค.
  1. A ํŠธ๋žœ์žญ์…˜์ด ๋จผ์ € ์ˆ˜๋Ÿ‰ ๋ณ€๊ฒฝ์„ ํ•œ๋‹ค.
  1. ๊ทธ๋ฆฌ๊ณ  ๋˜ ๊ฑฐ์˜ ๋™์‹œ์— B ํŠธ๋žœ์žญ์…˜์ด ์ˆ˜๋Ÿ‰์„ ๋ณ€๊ฒฝํ•œ๋‹ค.
  1. 2๋ฒˆ, 3๋ฒˆ ๋ณ€๊ฒฝ ์‹œ์ฐจ ์ฐจ์ด๊ฐ€ ๊ฑฐ์˜ ์—†๋‹ค๋ณด๋‹ˆ๊นŒ 2๊ฐ€ ๋ณ€๊ฒฝ๋˜์–ด์„œ ์ปค๋ฐ‹๋˜๊ธฐ ์ „์— 3๋„ ๋ณ€๊ฒฝ ์‹œ๋„๋ฅผ ํ•จ

๐Ÿ” ์›์ธ

์ˆ˜์ •์ผ์‹œ ์ปฌ๋Ÿผ์ด ๋ฐ€๋ฆฌ์ดˆ(millisecond) ๋‹จ์œ„๊นŒ์ง€ ์ €์žฅํ•˜์ง€ ์•Š๊ณ , ์‹œ๋ถ„์ดˆ(second) ๋‹จ์œ„๊นŒ์ง€๋งŒ ์ €์žฅํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๋ฐœ์ƒํ•˜๋Š” ๋ฌธ์ œ์˜€๋‹ค. ์ด ๊ฒฝ์šฐ ๊ฐ™์€ ์ดˆ ๋‚ด์— ์—ฌ๋Ÿฌ ํŠธ๋žœ์žญ์…˜์ด ๋™์‹œ์— ๋ฐ์ดํ„ฐ๋ฅผ ์ˆ˜์ •ํ•˜๊ฒŒ ๋˜๋ฉด ์ˆ˜์ •์ผ์‹œ๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ๋ณ€๊ฒฝ์„ ๊ฐ์ง€ํ•˜๋Š” ๊ฒฝ์šฐ ์ •ํ™•ํ•˜๊ฒŒ ๋™์ž‘ํ•˜์ง€ ์•Š์„ ์ˆ˜ ์žˆ๋‹ค. ํŠนํžˆ ๊ณ ์†์œผ๋กœ ์ฒ˜๋ฆฌ๋˜๋Š” ํŠธ๋žœ์žญ์…˜ ํ™˜๊ฒฝ์—์„œ๋Š” ๊ฐ™์€ ์ดˆ ๋‚ด์— ์—ฌ๋Ÿฌ ๋ฐ์ดํ„ฐ๊ฐ€ ๋ณ€๊ฒฝ๋  ๊ฐ€๋Šฅ์„ฑ์ด ๋†’๋‹ค.

โœ…ย ํ•ด๊ฒฐ๋ฐฉ๋ฒ•

  1. prod_opt ํ…Œ์ด๋ธ”์˜ timestamp ์ปฌ๋Ÿผ์˜ ํƒ€์ž…์„ timestamp(3)์œผ๋กœ ๋ณ€๊ฒฝ
  1. UPD_DTTM ๊ฐ’์„ ๋„ฃ์–ด์ค„ ๋•Œ now()๊ฐ€ ์•„๋‹Œ CURRENT_TIMESTAMP(3)๋กœ ๋„ฃ์–ด์ฃผ๋„๋ก ์ฟผ๋ฆฌ ๋ณ€๊ฒฝ
<select id="selectProductQty" parameterType="int" resultType="ProdOptDTO">
    SELECT PO.PROD_ID, PO.OPT_COMB_NO, PO.INV_QTY, PO.UPD_DTTM
    FROM PROD_OPT PO
    WHERE OPT_COMB_NO IN
    <foreach collection="array" item="optCombNoArr" open="(" close=")" separator=",">
        #{optCombNoArr}
    </foreach>
</select>

<update id="decreaseProdQty" parameterType="Map">
    UPDATE prod_opt
    SET INV_QTY = INV_QTY - #{qty}
      , UPD_DTTM = CURRENT_TIMESTAMP(3)
    WHERE OPT_COMB_NO = #{optCombNo}
      AND UPD_DTTM = #{updDttm}
</update>

Uploaded by N2T