인프런 커뮤니티 질문&답변

한지찬님의 프로필 이미지
한지찬

작성한 질문수

재고시스템으로 알아보는 동시성이슈 해결방법

'Synchronized 이용해보기' 강의에서 질문이 있습니다.

작성

·

229

0

제가 이해한 바는 다음과 같습니다.

 

Transactional 어노테이션을 사용시

  • 해당 메서드나 클래스 내의 모든 메서드가 하나의 트랜잭션으로 묶여 처리

 

synchronized를 사용시

  • 동시에 같은 객체의 특정 메서드를 여러 스레드가 호출하지 못하게 하는 데 사용

 

그런데 1분 29초부터 설명을 들어보면

decrease 함수 안에서,

endTransaction을 수행하기 전에 다른 스레드가 decrease 메소드를 호출할 수 있다고 하셨습니다.

 

그런데 이 부분이 이해가 안됩니다. synchronized 키워드를 붙였다면, 동시에 같은 객체의 메서드를 다른 스레드가 호출하지 못하는것 아닌가요?

 

Transactional 어노테이션을 주석처리하면 동작하던데,

이 여부와 관계 없이 동작해야하는것 아닌가요?

 

답변 1

0

최상용님의 프로필 이미지
최상용
지식공유자

한지찬님 안녕하세요.
Spring 에서는 Transactional 어노테이션을 사용하면 해당 클래스를 래핑하는 클래스를 만들어서 처리합니다.
예를들면 아래와 같은 모습을 띠고있습니다.

class StockServiceWithTransactional {

    StockService stockService;

    public void decrease(Long quantity) {
        transaction.start()
        stockService.decrease(quantity)
        transaction.commit()
    }
}

이때 StockService 의 decrease 메소드에는 synchronized 가 붙어있으므로 메소드에는 1개의 스레드만 접근하는 것이 보장됩니다.
하지만 데이터베이스에 커밋을 하는 동안 다른 스레드가 StockService 의 decrease 메소드에 접근할 수 있게 됩니다.

이러한 이유로 Transactional 을 붙였을 때 문제가 발생하는 것입니다.

감사합니다.

한지찬님의 프로필 이미지
한지찬
질문자

아아... 하기와 같이 이해하면 될까요!?

  1. stockService.decrease(quantity) 이 메소드는 한번의 하나의 스레드만 접근할 수 있다.

  2. 하나의 스레드가 stockService.decrease(quantity)를 지나서 transaction.commit 하는 시점에 다른 스레드가 stockService.decrease(quantity)를 수행할 수 있다.

     

 

잠시 착각했던것 같습니다.

stockService.decrease(quantity) 이 메소드가 아닌,

public void decrease(Long quantity){} 이 메소드가 synchronized 되었다고 착각했네요...

최상용님의 프로필 이미지
최상용
지식공유자

넵넵! 말씀해주신대로 이해하시면 될 것 같습니다 😄

한지찬님의 프로필 이미지
한지찬

작성한 질문수

질문하기