24.06.19 13:28 작성
·
177
·
수정됨
0
@Service
public class StockService {
private final StockRepository stockRepository;
public StockService(StockRepository stockRepository) {
this.stockRepository = stockRepository;
}
// @Transactional
public synchronized void decrease(Long id, Long quantity) {
// Stock 조회
Stock stock = stockRepository.findById(id)
.orElseThrow(EntityNotFoundException::new);
// 재고 감소
stock.decrease(quantity);
// 갱신된 값을 저장
// stockRepository.save(stock);
}
}
안녕하십니까! 제가 알기로는 영속성 컨텍스트의 변경감지 기술로 인해서 별도의 save 메서드를 실행하지 않아도 값이 update 되는 걸로 알고있는데 그럴 경우 @Transactional를 제거하면 영속성 컨텍스트로 관리하지 않기 때문에 테스트를 진행하면 오류가 발생하고있습니다ㅠㅠ 혹시 제가 잘못된 지식을 갖고있는건가요?ㅠ
답변 2
0
안녕하세요, 인프런 AI 인턴입니다.
님의 질문에 답변드립니다.
예, 님께서 말씀하신 것처럼 @Transactional
어노테이션이 없으면, 해당 메서드는 하나의 트랜잭션으로 관리되지 않습니다, 즉 영속성 컨텍스트에서 변경 감지(Dirty Checking) 기능을 사용할 수 없게 됩니다. JPA에서는 영속 상태의 엔티티에 대한 변경 사항이 트랜잭션이 커밋될 때 데이터베이스에 자동으로 반영되는데, 이 기능은 트랜잭션 안에서 동작합니다.
따라서 @Transactional
을 제거하면, 트랜잭션의 관리 및 영속성 컨텍스트의 생명 주기 관리가 이루어지지 않아 변경 감지가 동작하지 않습니다. 결과적으로 엔테티의 상태 변화가 데이터베이스에 반영되지 않아 오류가 발생하는 것입니다.
실제로 엔티티의 상태 변경을 데이터베이스에 반영하려면 트랜잭션 내에서 엔티티의 상태를 변경하고, 해당 트랜잭션이 성공적으로 완료되어 커밋되어야 합니다. 따라서 @Transactional
어노테이션을 메서드에 추가하여 메서드 전체를 하나의 트랜잭션으로 관리할 필요가 있습니다.
즉, 메서드에서 동작하는 모든 데이터베이스 연산을 하나의 작업 단위로 묶어주어야 하며, 이를 통해 데이터의 일관성을 보장받을 수 있습니다. @Transactional
을 사용함으로써 여러분이 하고자 하는 변경이 모두 성공할 경우에만 실제 데이터베이스에 반영됩니다.
결론적으로, @Transactional
을 사용하여 메서드를 트랜잭션으로 처리해야 영속성 컨텍스트의 변경 감지 기능을 이용할 수 있으멀로, 오류 없이 엔티티의 변경 사항을 데이터베이스에 반영할 수 있습니다.
2024. 06. 23. 23:16
저의 질문이 명확하지 않았던 같습니다ㅠ
즉 synchronized를 사용할 경우 영속성 컨텍스트로 관리를 못한다는것으로 이해해도 괜찮을까요?