목록Java (10)
훈훈훈
Introduction 블로그 포스팅 스터디에서 스터디원과 Spring default isolation level 이 어떻게 결정 되는지 토론을 하게 되었다. 토론 도중에 스터디원분이 관련 StackOverFlow 글을 찾고 공유해주셨는데, 글 내용은 MySQL connectror/J 는 default isolation level 로 READ_COMMITTED 를 제공한다는 것이다. 실제로 코드 레벨에서 살펴보니 진짜 READ_COMMITTED 로 제공이 되고 있었다. 내가 알던 내용은 MySQL 은 storage engine 으로 innoDB 를 사용하는 경우 default isolation level 로 REPEATABLE_READ 를 제공한다는 것이다. 그렇기 때문에 MySQL connector/J..
이슈 얼마전에 검색 API 를 호출하면 데이터가 종종 빈 값이 반환되는 이슈가 있었다. 이슈가 발생하는 시점은 Indexer 어플리케이션에서 Elasticsearch 인덱스에 Bulk Insert 할 때 였다. 해당 시점에 데이터를 조회 하였을 때, 데이터가 비어있는 현상을 발견하였다. 이슈가 발생한 원인은 Elasticsearch 는 refresh interval 기능이 존재하기 때문이다. Elasticsearch 공식문서를 확인해보면 아래와 같이 설명을 하고 있다. 해당 기능은 디폴트로 1s 마다 refresh interval 를 수행하게 되는데, 우리가 Elasticsearch 에서 조회하는 내용은 1s 이전 데이터를 의미한다. 엄밀하게는 지난 30s 동안 한 번 이상의 검색 요청을 받은 인덱스에 ..
이슈 Spring data elasticsearch 를 사용하여 색인을 하면 아래와 같이 _class 라는 필드가 자동 생성이 되는 것을 볼 수 있다. 해당 필드는 sava 메소드를 호출할 때 사용했던 도큐먼트 객체에 대한 정보를 담고 있지만, Elasticsearch 를 호출하는 클라이언트 입장에서는 불필요한 데이터이다. 따라서 굳이 저 필드를 생성할 필요는 없다고 생각한다. _class 필드가 존재하는 목적이 궁금하여 스택오버플로우를 검색해보니, spring data elasticsearch 프로젝트를 리드하시는 분의 답변을 찾을 수 있었다. 100% 이해가 되는 문장은 아니지만 상속 관련 된 객체를 사용할 때 사용하는 필드라고 한다. 그렇다면 상속을 하지 않는 도큐먼트 객체들에 대해서는 해당 필드는..
Introduction 이번에 HighLevelRestClient 를 사용하여 운영하던 Indexer 어플리케이션에 Spring Data Elasticsearch 를 적용 해보게 되었다. 새로운 라이브러리를 적용 후 Alias 를 사용한 Rollover Index 기능 구현은 프레임워크 버전에 따라 구현 방법이 조금씩 다른 것 같아 적절한 레퍼런스를 찾기가 좀 어려웠었다. 다행히 스택오버플로우를 보다가 Spring Data Elasticsearch 프로젝트 리드하시는 분의 블로그에 좋은 글을 찾아 쉽게 해결할 수 있었고, 관련해서 내용을 정리해보려고 한다. 에제 코드는 Github 에서 확인해볼 수 있다. Rollover Index 위 그림을 보듯이 요청을 alias 이름으로 받고 데이터는 alias 와..
Introduction 사내에서 Local cache 라이브러리인 Caffeine cache 를 도입하게 되어 공부한 내용을 정리하게 되었다. Caffeine cache 를 사용하면서 EhCache 와의 차이점이 궁금하여 두 라이브러리를 비교 후 간단한 예제 코드를 살펴보려고 한다. 예제 코드는 깃헙에서 확인할 수 있다. Caffeine cache vs EhCache 3.xx 먼저 Caffeine cahce 에 대하여 살펴보자 Baeldung 에서는 Caffeine Cache 를 아래와 같이 소개하고 있다. Caffeine 깃헙 위키는 아래와 같이 소개하고 있다. 공통적으로 High Performance Java caching Library 라고 소개하고 있다. 문서를 읽어보면 캐시와 Concurrent..
Introduction 이번에는 Multiple DataSource 환경에서 JPA 로 개발 된 Repository 테스트를 할 때 사용하는 @DataJpaTest 로 테스트를 작성할 때 발생하는 문제, 그리고 어떻게 해결해야하는지에 대하여 정리해보려고 한다. 참고로 MyBatis 를 사용한다면, mybatis-spring-boot-starter-test 에 있는 @MyBatisTest 를 사용하면 된다. @DataJpaTest 는 JPA, Entity Manager 를 @MyBatisTest 는 MyBatis 를 AutoConfiguration 을 하는 점 이외에는 동일하다. 예제 코드는 GitHub 에서 확인할 수 있다. Problem 결론부터 말하자면 여러 DataSource 를 구성할 때 프로퍼티..
Introduction WebClient 를 사용하여 외부 API 를 Mock 기반 테스트를 할 때, response 값에 대한 stub 객체를 만드는 방법에 대하여 정리해보려고 한다. 전체 코드는 Github 에서 확인할 수 있다. Problems 일반적으로 Mockito 를 사용할 때 아래와 같은 방법으로 stub 객체를 만들 수 있다. ( Mockito 는 BDD 방식을 지원하기 때문에 when( ) 대신 좀 더 가독성이 좋은 given ( ) 을 사용하였다. ) given(webClientWrapper.get() .uri("http://localhost:8080/test") .retrieve() .bodyToMono(String.class) .block() ).willReturn("ok"); 하지..
아래 내용은 스프링 공식문서 스터디에서 정리했던 자료 입니다. Task Execution and Scheduling 1. Executor (1) Executor 란? Java 5에 도입되었으며, 단순히 void execute(Runnable command); 메서드만 정의된 객체이다. command 를 실행할 때 마다 새로운 스레드에 동작 command 는 Runnable 인터페이스 객체이다. Executor 가 실행될 때는 쓰레드를 명시하지 않는다고 한다. 그 역할은 Runnable 인터페이스가 대신한다. executor.execute(new RunnableTask()); 이런 식으로 command 를 실행 시킨다. (2) Runnable Interface 자바에서는 Thread 를 구현할 때 Thre..