🧑🏻‍💻 비관적 Lock 이란?

<aside> 💡 실제 DB 행에 Lock을 걸어서 정합성을 맞추는 방법

</aside>

Pessimistic Lock 종류

비관적 Lock 진행

비관적 Lock 전체 코드

  1. 결제 할 상품을 찾을 때, 비관적 LOCK을 건다.

    @Lock(LockModeType.PESSIMISTIC_WRITE)
    @Query("select p from Product p where p.id = :productId")
    Optional<Product> findByIdWithPessimistic(@Param("productId") Long productId);
    
  2. findByIdWithPessimistic를 사용하여 결제할 상품을 DB에서 조회한다.

    @Transactional
        public int orderProductWithLock(String pgToken, Long memberId)
    
    	 ' ' ' ' ' '
    
            Product product = productRepository.findByIdWithPessimistic(Long.valueOf(productId))
                .orElseThrow(() -> new ProductNotFoundException(ErrorCode.PRODUCT_NOT_FOUND));
    
    		' ' ' ' ' '
    
            product.saleProduct(); //쿼리 2
            paymentHistoryRepository.save(paymentHistory); //쿼리 1
            System.err.println("종료");
            return product.getStock();
            //트랜잭션.커밋
        }
    
  3. 비관적 Lock 테스트 코드

    // 동시성 테스트 시작 ====================================================================
    int threadCount = 3;
    ExecutorService executorService = Executors.newFixedThreadPool(threadCount);
    CountDownLatch latch = new CountDownLatch(threadCount);
    
    List<Exception> exceptionList = new ArrayList<>();
    
    for (int i = 0; i < threadCount; i++) {
        int finalI = i;
        executorService.submit(() ->{
            try {
                paymentService.orderProductWithLock("asg", memberList.get(finalI).getId());
            } catch (Exception e) {
                e.printStackTrace();
                exceptionList.add(e);
            } finally {
                latch.countDown();
    
            }
        });
    }
    latch.await();
    Assertions.assertThat(exceptionList.get(0) instanceof PessimisticLockingFailureException);
    

🚀 트러블 슈팅 | 결과 | 성능테스트

결과

Untitled

Untitled

추가 진행