inflearn logo
강의

강의

N
챌린지

챌린지

멘토링

멘토링

N
클립

클립

로드맵

로드맵

지식공유

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

Pessimistic Lock 활용해보기

saveAndFlush 와 synchronized

382

YOGURT

작성한 질문수 30

0

https://www.inflearn.com/questions/655574

위에 질문에서 saveAndFlush를 사용한 이유에 "save 메소드를 사용하게 된다면 데이터베이스에 바로 flush 가 되는것이 아니기때문에 synchronized 를 이용한 방법을 테스트할 때 오류가 날것입니다." 라고 답변해주셨는데 save를 사용하든 saveAndFlush를 사용하든 문제가 발생하지 않나요?
flush를 바로 해준다고 데이터베이스에 커밋이 되는게 아니기때문에 충분히 동시성 문제가 생길 수 있다고 생각됩니다.

 

결국 아래 코드에서 saveAndFlush를 사용하든 save를 사용하든 실패하는것인데 왜 saveAndFlush를 사용하면 오류가 안난다고 하신건지 궁금합니다.

@Transactional
public synchronized void decrease(Long id, Long quantity) {
    Stock stock = stockRepository.findById(id).orElseThrow();
    stock.decrease(quantity);
    
    stockRepository.saveAndFlush(stock);
}


java spring 동시성

답변 2

0

최상용

YOGURT 님 안녕하세요.

답변이 늦어져서 죄송합니다.
첨부해주신 코드에서는 saveAndFlush 를 사용하여도 오류가 발생합니다.
트랜잭션이 커밋되기 전에 다른스레드가 해당 메소드에 접근이 가능하기 때문입니다.
사실 에러가 발생하는 것은 Transactional 의 동작방식과 synchronized 의 동작방식때문인데 제가 설명을 잘못 드린것 같습니다 ㅠㅠ

혼란을 드려서 죄송합니다.
해당 강의에서 전달하고자 했던 것은 "Transactional 의 동작방식과 synchronized 동작방식 나아가 1개의 스레드만 접근이 가능해야하고, 그 스레드가 데이터베이스의 업데이트까지 하고난 후 다른스레드가 접근이 가능하게 해야한다" 입니다.

0

최상용

첨부해주신 질문의 답글도 업데이트를 하였습니다.
질문주셔서 감사합니다!

다른 질문이 있다면 추가로 남겨주세요!

0

YOGURT

이해했습니다 너무 감사합니다!

0

인프런 AI 인턴

안녕하세요, 인프런 AI 인턴입니다.

저장된 엔티티를 처리할 때 save 메소드와 saveAndFlush 메소드는 다른 점이 있습니다. save 메소드는 트랜잭션이 종료될 때까지 영속성 컨텍스트에만 상태 변경을 보관하고, 트랜잭션의 끝에서 데이터베이스에 반영합니다. 반면, saveAndFlush 메소드는 더 즉시 데이터베이스에 flush를 수행하여 SQL 실행을 강제합니다. 그러나 flush는 단지 SQL 실행을 강제할 뿐, 실제로 데이터베이스 트랜잭션이 커밋되어 변경사항이 적용되는 것은 아닙니다.

이러한 차이 때문에 귀하가 언급한 동시성 문제가 발생할 여지는 여전히 존재합니다. 트랜잭션이 진행되는 동안 다른 트랜잭션으로부터의 접근이나 변경에 대하여 데이터베이스 레벨에서 격리수준(isolation level) 설정이 중요하게 작용하게 됩니다.

예시 코드에서 saveAndFlush 사용이 오류를 방지할 것이라는 설명은 다소 혼란을 일으킬 수 있습니다. 실제로 동시성 제어를 위해서는 JPA의 격리수준, 트랜잭션 범위, 락(locking) 전략 등 다양한 요소를 고려해야 합니다. synchronized 키워드는 자바 애플리케이션 안에서 메서드 수준의 동시성 제어를 의미하여, 여러 스레드가 하나의 인스턴스에 동시에 접근하지 못하게 하지만, 분산 시스템에서의 동시성 문제까지 해결하지는 못합니다.

즉, saveAndFlush를 사용하더라도 데이터베이스 레벨에서의 격리 수준 및 다른 트랜잭션 관리 전략이 없다면, 동시성 문제에 대한 충분한 대비가 되지 않음을 명심해야 합니다. JPA의 트랜잭션 동작과 관련한 상세한 정보는 Spring Data JPA 문서에서 확인할 수 있으며, 다음의 문서를 참고하시면 도움이 될 것입니다.

이러한 정보를 바탕으로 동시성 문제에 대한 보다 구체적이고 깊이 있는 접근을 하실 수 있을 것입니다.

레디선 테스트코드에서 채널이름은 없어도 되는건가요?

0

43

2

낙관적 락을 사용할 떄 차이점

0

119

2

동시성 검증 코드에 관한 문의

0

94

2

단일연산

0

70

2

낙관적락vs. 레디스락

0

108

2

안녕하세요. 레디슨 질문있습니다..!!

0

67

2

@Lock(OPTIMISTIC)이 필요한 이유

0

90

2

get_lock 의 timeout이 3000초 이던데 너무 긴거 아닌가요?

0

131

2

DataSource Hikari 사용 이유

0

145

2

saveAndFlush 사용 이유 문의

0

112

3

비관적 락 VS 네임드 락

0

159

3

application.yaml 에 redis 정보

0

99

2

왜 클래스 이름에 Facade 가 붙나요?

0

183

2

@Transactional 으로 인한 동시성 문제 발생 원인이 궁금합니다.

0

219

2

@modifying 이용한 동시성 제어

0

168

2

DB락과 분산락

0

260

2

NamedLock 테스트 실패

0

186

2

테스트에서 트랜잭션 어노테이션 질문 있습니다.

0

172

2

optimistic Lock 재시도 질문입니다.

0

230

2

낙관적 락 테스트 실패

0

239

2

오류?

0

1626

4

LettureLockStockFacadeTest에서 오류가 발생합니다.

1

268

2

Pessimistic Lock 전체 테스트 오류 문의

0

359

3

비관적 락 vs 레디스(Lettuce)락 비교 관련 질문

0

460

2