BackEnd/스프링
-
동시성 제어 syncronized와 @TransactionalBackEnd/스프링 2022. 9. 26. 14:51
서비스에 @Transactional 어노테이션만 붙이면 동시에 자원에 접근하는 스레드들에 레이스 컨디션이 발생했을 경우, 기대와 다르게 동작할 수 있다. @RequiredArgsConstructor @Service public class StockService { private final StockRepository stockRepository; @Transactional public void decrease(Long id, Long quantity){ Stock stock = stockRepository.findById(id).orElseThrow(); stock.decrease(quantity); stockRepository.saveAndFlush(stock); } } 1. 트랜잭션이 시작되는 메서드..
-
-
-
@Profile 대신 @ConditionalOnProperty 을 사용하라BackEnd/스프링 2022. 8. 3. 14:34
@Profile("local") 와 같은 사용은 코드가 string 으로 정의한 Profile 에 의존하게 하며, 여기저기 퍼진 Profile 정의는 1. String 정의가 변경이 됐을 때 텍스트로 코드 전체 검색을 통해 수정을 해야한다. 2. 특정 환경에서 애플리케이션이 어떤 코드로 동작하는지 파악하기 어렵다. 3. test, h2, prod 등 여러 환경과 활성화시킬 데이터 베이스 등이 Profile로 정의되면 특정 profile 활성화, 비활성화 여부나 멀티 profile 활성화 시에 애플리케이션의 동작방식을 파악하기 어렵다. 4. @Profile("!test") 같은 코드까지 섞여있다면 더 파악하기 어려워질 수 있다. 그래서 Profile 대신에 application-{profile}.yml/p..
-
ControllerTest - Pageable, SearchDTOBackEnd/스프링 2022. 8. 2. 16:21
응답데이터 { "content": [ { "id": 1, "title": "welcome", "content": "hello world", "categoryName": "spring", "email": "seung90@gmail.com", "viewCount": 3 } ], "pageable": { "sort": { "unsorted": true, "sorted": false, "empty": true }, "pageNumber": 0, "pageSize": 20, "offset": 0, "paged": true, "unpaged": false }, "totalPages": 1, "totalElements": 1, "last": true, "numberOfElements": 1, "first": true..
-
-
BDDMokito.given return nullBackEnd/스프링 2022. 7. 29. 16:31
Controller 에서는 BoardRequest 를 받고, 서비스는 Board 를 받아 Mocking 할 때 특정 Board 를 생성해 given 인자로 사용하면 항상 null이 반환된다. 테스트 코드에서 들어가는 request 와 서비스 Mocking 에 인자는 다른 객체이기 때문에 any 로 타입명시를 해줘 해결했다. given(boardService.save(any(Board.class) )).willReturn(board); String body = objectMapper.writeValueAsString(boardRequest); mockMvc.perform(post("/api/boards") .content(body) .contentType(MediaType.APPLICATION_JSON))..