전체 글
-
SpringApplicationRunner란? (+ 동작과정)Spring Framework 2023. 9. 8. 00:01
개요 Spring Boot를 실행했을 때 매번 특정 코드를 호출하는 방법에 대해 알아보다가 알게 된 Spring ApplicationRunner에 대해서 알아보고자 합니다. ApplicationRunner @FunctionalInterface public interface ApplicationRunner { /** * Callback used to run the bean. * @param args incoming application arguments * @throws Exception on error */ void run(ApplicationArguments args) throws Exception; } Bean이 SpringApplication 내에 포함될 때 실행되어야 함을 나타내는 데 사용되는 인..
-
놓치기 쉽지만 중요한 @Transactional RollbackSpring Framework 2023. 9. 7. 00:01
개요 트랜잭션에 대해서 놓치기 쉬운 개념들을 정리해보고자 합니다. 최대한 많은 내용을 담기 위해 핵심개념위주로 글을 작성해보고자 합니다. Spring의 @Transactional 이란? 트랜잭션이란 데이터베이스에서 주로 사용하는 개념으로 이 연산이 한 번에 묶여서 일어나야 하는지 전부 일어나지 말아야 하는지를 단위를 묶어줄 때 사용합니다. 예를 들어 어떤 시스템에서 회원이 가입하면 이름과 나이를 저장하고 조회해서 사용해야 합니다. 1. 회원가입을 수행할 때 첫 번째로 회원의 이름을 DB에 저장했습니다. 2. 두 번째로 회원의 나이를 DB에 저장했습니다. 이때 2번째 작업을 수행하다가 예상치 못한 오류가 발생했다면 회원의 이름만 남아있고 나이는 존재하지 않는데 이런 의도치 않는 상황에서 데이터 정합성을 지..
-
ServletRequest 여러번 읽기 - ContentCachingRequestWrapperSpring Framework 2023. 9. 6. 00:01
개요 Spring에서 request/response를 다루게 되면 HttpServletRequest/HttpServletResponse를 사용합니다. 이때 최상위 인터페이스는 ServletRequest이며 getInputStream의 경우에는 한 번만 읽을 수 있습니다. 만약 이미 한번 request값을 읽고, 컨트롤러에서 @RequestBody로 2번 읽으려 한다면 HttpMessageNotReadableException가 발생하게 됩니다. 또는 이미 Reader를 사용했다면 다음과 같은 예외 메시지가 나타납니다. java.lang.IllegalStateException: getInputStream() has already been called for this request 이때 Sprinrg의 Con..
-
공식문서로 알아보는 Redis persistence프로젝트/redis 2023. 9. 5. 00:01
개요 Redis는 In-memory 시스템으로 동작하지만 disk에 영구저장하는 기능도 지원합니다. 어떤 방식으로 저장하는지에 대해 Redis 공식문서를 기반으로 Redis Persistence에 대해 알아보고자 합니다. Redis는 어떻게 데이터를 disk에 저장할까? Persistence란 SSD와 같은 내구성 있는 스토리지에 데이터를 기록하는 것을 의미합니다. Redis는 이에 대해 다양한 방법론을 제시합니다. Redis DataBase(RDB) : 지정된 간격으로 데이터 집합의 특정 시점 스냅숏을 저장합니다. Append Only File(AOF) : 모든 write operation을 기록하고, 서버 시작 시 원래 데이터세트를 재구성할 수 있습니다. No Persistence : 지속성을 완전히..
-
JPA Persistable으로 성능최적화 해보기JPA 2023. 9. 4. 00:01
개요 JPA에서 @GenerateValue를 사용하지 않고, ID를 직접 생성하는 경우 save = insert를 수행할 때 select 쿼리가 한번 나가는 경험을 하게 되어 왜 그런지? 어떻게 개선할 수 있는지 알아보고자 합니다. JPA에서 Save는 어떻게 동작할까? 저장하려는 엔티티가 새로운 엔티티라면 persist 저장하려는 엔티티가 새로운 엔티티가 아니라면 merge @Transactional @Override public S save(S entity) { Assert.notNull(entity, "Entity must not be null"); if (entityInformation.isNew(entity)) { em.persist(entity); return entity; } else { r..
-
코틀린(kotlin) - 문자열계산기프로젝트/Kotlin + TDD 2023. 9. 3. 00:01
개요 사내스터디를 통해 문자열계산기를 각자 만들어보고 코드리뷰하는 시간을 가졌습니다. 이때 구현했던 코드와 고민들을 공유해보고자 합니다. 코드는 github 저장소에서 보실 수 있습니다. https://github.com/Junuu/kotlin-racingcar/tree/junuu 요구사항정리 - Readme.md 기능구현에 대해 요구사항을 정리하고 단계별로 구현해 나갔습니다. 초기에 덧셈, 뺄셈까지는 코드의 구조를 잡느라 시간이 오래 걸렸지만 이후에는 금방금방 구현이 가능했습니다. Calculator Object object Calculator { fun runCalculator(input: String?): Int { val elementStorage = CalculatorInputClassifier..
-
ULID란 무엇일까?카테고리 없음 2023. 9. 2. 00:01
개요 보통 UUID를 통해 식별자의 고유값을 보장해 주거나 twitter의 snowflake를 활용하곤 합니다. 또한 ULID라는 개념도 알게 되었는데, ULID란 무엇일까요? ULID의 등장배경 UUID를 사용하게 되면 정렬 없이 무작위의 값을 생성해 냅니다. 그러면 어떤 식별자가 먼저 만들어진 건지? 알 수 없습니다. 이를 해결하기 위해 ULID가 등장하게 됩니다. ULID란? Universally Unique Lexicographically Sortable Identifier의 약자로 대소문자를 구별하지 않는 시간을 나타내는 26글자와 16글자의 임의의 값으로 구성되어 있습니다. 한국어로 번역해 보면 Lexicographically(사전적으로) Sortable(정렬가능한) Universally Un..
-
Kotlin Value Class란?Kotlin 2023. 9. 1. 00:01
개요 코틀린에서는 VO(Value Object)를 어떻게 만드는지 알아보다가 Value Class에 대해 알게 되었습니다. VO란 특정한 비즈니스값을 담는 객체라고 합니다. Kotlin 1.5에 출시된 기능입니다. Kotlin의 Value Class란? 비즈니스 로직에서 특정 type에 대한 wrapper class를 생성해야 하는 경우가 있을 수 있습니다. 하지만 추가적인 heap alloation으로 런타임이 오버헤드가 발생하게 됩니다. 특히 래핑 된 타입이 원시타입(primitive type)인 경우에는 런타임에 크게 최적화되는데 이런 장점을 누리지 못합니다. 이런 문제를 해결하기 위해 kotlin에서는 inline class를 소개합니다. value class Password(private val..