동시성 문제 해결

Haley Young·2023년 1월 3일
0

pessimistic lock

DB에 직접 락(lock)을 거는 방법

  @Lock(PESSIMISTIC_WRITE)
  @Query("select s from Stock s where s.id = :id")
  Stock findByIdWithPessimisticLock(Long id);

Spring Jpa 에서 findById 대신에 @Lock 을 사용한 메서드를 사용하면 된다.

제일 간편하나 Transaction이 필요하다.

optimistic lock

version 처리를 하여 사용하는 방법

@Entity 에 @Version 값이 있어야 한다. Transaction이 필요없다.
그러므로 에러 해결을 직접 해주어야 한다

 		while (true) {
            try {
                stockService.decrease_optimistic_lock(id, quantity);

                break;
            } catch (Exception e) {
                Thread.sleep(58);
            }
        }

named lock

MySql 에서 get_lock() 함수를 사용하여 직접 락을 걸고 release_lock() 으로 락을 풀어 사용하는 방법.
많이 쓰이는 방법은 아닌 것 같다 (아무래도 직접 락을 걸고 해제한다는 게 에러가 발생할 확률을 높힐 것 같다...)

	try {
    	stockRepository.getLock(id.toString());

		Stock stock = stockRepository.findById(id).orElseThrow(() -> new
            						RuntimeException("아이템이 존재하지 않습니다"));
                                    	
        stock.decrease(quantity);
        stockRepository.saveAndFlush(stock);
    } finally {
        stockRepository.releaseLock(id.toString());
    }
	@Query(value = "select get_lock(:key, 3000)", nativeQuery = true)
    void getLock(String key);

    @Query(value = "select release_lock(:key)", nativeQuery = true)
    void releaseLock(String key);
profile
Just keep coding🎶 Just keep coding🎵

0개의 댓글