멋사 Backend Plus 33일차 🦁

μ‹ μž¬μ›Β·2023λ…„ 12μ›” 9일

μ˜€λŠ˜μ€ μ˜€μ „μ— μ·¨μ—… νŠΉκ°•μ΄ μžˆμ—ˆκ³ , μ˜€ν›„μ—λŠ” ν”„λ‘œμ νŠΈ 진행을 ν•˜μ˜€λ‹€.

μ˜€μ „

λ©‹μ‚¬μ—μ„œ λ‚˜μ˜€μ‹  νŒ€μž₯? λ‹˜μ΄ λ‚˜μ˜€μ…”μ„œ μ„€λͺ… ν•΄μ£Όμ…¨λŠ”λ°, λŒ€λž΅μ μΈ λ‚΄μš©μ€ μ΄λž¬λ‹€.

μ›ν‹°λ“œ 톡계λ₯Ό 보면 κΈ°λ³Έ 60개 이λ ₯μ„œλ₯Ό μž‘μ„±ν•΄μ•Ό 1κ°œκ°€ λΆ™λŠ”λ‹€ μ˜€μœΌλ©°, λŒ€μ²΄λ‘œ λ°±μ—”λ“œ κ°œλ°œμžλŠ” κ·Έλ‚˜λ§ˆ 많이 λ½‘λŠ”λ°, μ‹ μž…μ„ λ½‘λŠ” λΉˆλ„μˆ˜κ°€ ν™•μ—°νžˆ μ€„μ—ˆλ‹€κ³  ν•œλ‹€. μ›ν‹°λ“œλŠ” μž‘μ½”λ¦¬μ•„, μ‚¬λžŒμΈκ³Ό 같은 μ·¨μ—… 포털 μ‚¬μ΄νŠΈ 이닀.

μ˜€ν›„

  • 였늘 μ˜€ν›„μ—λŠ” μƒν’ˆ 재고 μˆ˜λŸ‰μ— λŒ€ν•΄ λ©€ν‹° μ“°λ ˆλ“œ ν™˜κ²½μ—μ„œ λ™μ‹œμ„± λ¬Έμ œκ°€ λ°œμƒν•  것 κ°™μ•„, νŒ€μ›λ“€κ³Όμ˜ 토둠도 μ§„ν–‰ν•˜μ˜€κ³ , μ˜κ²¬μ„ μ£Όκ³  λ°›λŠ” μ‹œκ°„μ΄ λ˜μ—ˆλ‹€.

➑ μ˜ˆμƒ μ‹œλ‚˜λ¦¬μ˜€λŠ” μ΄λŸ¬ν–ˆλ‹€. Aμœ μ €μ™€ Bμœ μ €κ°€ μžˆλ‹€κ³  μ‘΄μž¬ν•˜κ³ , λ“±λ‘λœ μƒν’ˆ 10κ°œμ— λŒ€ν•΄ μž₯λ°”κ΅¬λ‹ˆμ— μƒν’ˆμ„ 각각 1κ°œμ”© λ‹΄κ²Œλ˜λ©΄, μƒν’ˆμ˜ 재고 μˆ˜λŸ‰μ΄ 8κ°œκ°€ λ˜μ–΄μ•Ό ν•˜λŠ”λ° 9κ°œκ°€ λœλ‹€λŠ” 것 μ΄μ˜€λ‹€.

μ•„λž˜μ˜ μ½”λ“œλŠ” κ°„λ‹¨ν•œ λ™μ‹œμ„±μ„ ν…ŒμŠ€νŠΈ ν• μˆ˜μžˆλŠ” ν…ŒμŠ€νŠΈ μ½”λ“œμž…λ‹ˆλ‹€.
μƒν’ˆμ˜ κ°―μˆ˜κ°€ 20개인 κ°•μ•„μ§€ μ‚¬λ£Œλ₯Ό λ“±λ‘ν•˜μ˜€κ³ , 10개의 λ©€ν‹°μ“°λ ˆλ“œλ₯Ό μƒμ„±ν•˜μ—¬, 20번의 μž₯λ°”κ΅¬λ‹ˆμ— λ‹΄λŠ” 행동을 ν•˜μ˜€μŠ΅λ‹ˆλ‹€.

@Test
    public void λ™μ‹œμ—_20개_μš”μ²­() throws InterruptedException {
        product = Product.builder().productName("κ°•μ•„μ§€ μ‚¬λ£Œ")
                .price("25_000")
                .content("μœ ν†΅κΈ°ν•œ 1λ…„ 남은 μ‚¬λ£Œμž…λ‹ˆλ‹€.")
                .count(20)
                .build();
        productRepository.save(product);

        int threadCount = 20;
        // 10개의 μ“°λ ˆλ“œ 생성
        ExecutorService executorService = Executors.newFixedThreadPool(10);
        CountDownLatch latch = new CountDownLatch(threadCount);

        // 50번의 반볡
        for (int i = 0; i < threadCount; i++) {
            executorService.submit(() -> {
                try {
                    product.removeStock(1);
                    System.out.println(product.getCount());
                } finally {
                    latch.countDown();
                }
            });
        }
        latch.await();
        Product findProduct = productRepository.findById(1L).orElseThrow();

        System.out.println(findProduct.getCount());
        Assertions.assertThat(0).isEqualTo(findProduct.getCount());
    }

ν•΄λ‹Ή ν…ŒμŠ€νŠΈ μ½”λ“œλ₯Ό μ‹€ν–‰ 해보면,

μƒν’ˆ μ œκ³ κ°€ 20개이고, 20번의 μž₯λ°”κ΅¬λ‹ˆμ— λ‹΄λŠ” 행동을 ν•˜μ—¬, μž¬κ³ κ°€ 0κ°œκ°€ λ˜μ–΄μ•Ό ν•˜μ§€λ§Œ, ν…ŒμŠ€νŠΈ μ½”λ“œκ°€ μ‹€νŒ¨ ν•˜λŠ” 것을 μ•Œμˆ˜ 있고, μƒν’ˆμ˜ 재고 κ°―μˆ˜κ°€ μ΄μƒν•˜κ²Œ 좜λ ₯ λ˜λŠ” 것을 μ•Œ 수 μžˆμŠ΅λ‹ˆλ‹€.

μ΄λŸ¬ν•œ λ¬Έμ œμ μ€ "λ™μ‹œμ—" 데이터 μžμ›μ„ λ³€κ²½ν•˜λ €κ³  ν• λ•Œ λ°œμƒ ν•©λ‹ˆλ‹€.

μ—¬κΈ°μ„œ 이제 비관적 락과 낙관적 λ½μ΄λΌλŠ” κ°œλ…μ΄ λ‚˜μ˜€λŠ”λ°, 이 뢀뢄에 λŒ€ν•΄μ„œλŠ” ν”„λ‘œμ νŠΈμ— μ μš©ν•΄λ³΄λ©° ν™•μ‹€νžˆ μ•Œμ•˜μ„λ•Œ 정리 해두면 쒋을 것 κ°™λ‹€.

0개의 λŒ“κΈ€