분류 전체보기699 AbstractAggregateRoot와 ApplicationEventPublisher 동작 과정 개요스프링의 이벤트 기능을 활용할 때 흔히 AbstractAggregateRoot 혹은 ApplicationEventPublisher를 사용한다. 이 글에서는 내부적으로 어떤 방식으로 동작하며, 이벤트가 어떻게 등록되고 발행되어 최종적으로 수신되는지 전체적인 과정을 정리해 본다. AbstractAggregateRoot 동작 과정AbstractAggregateRoot는 Spring Data에서 제공하는 추상 클래스로, 도메인 이벤트를 보다 손쉽게 등록하고 관리할 수 있도록 도와준다. 주로 DDD에서 상태 변경 후 외부에 의미 있는 이벤트를 전달할 때 사용된다. 예를 들어 주문이 완료되었을 때 도메인 이벤트를 등록하는 코드는 다음과 같다.@Entitypublic class Order extends Abstr.. 2025. 6. 28. 나는 GET으로 보냈는데 왜 POST로 갈까? (feat. OpenFeign 기여) 개요최근 OpenFeign을 사용할 때 이상한 문제를 겪었다. @FeignClient(name = "test-client")public interface TestClient { @GetMapping("/test") String getData(String query);}위와 같이 정의된 OpenFeign클라이언트를 통해 A 서버에서 B 서버의 API를 호출했는데, 405 Method Not Allowed 에러가 발생했다. 분명 B 서버에는 해당 API가 GET 메서드로 정확히 정의되어 있는데도 말이다.@Slf4jpublic class FeignLoggingInterceptorConfig { @Bean public RequestInterceptor requestLoggingInterce.. 2025. 5. 26. 하나의 트랜잭션 안에서 DDL과 DML을 함께 써도 될까? 개요결론부터 말하면 PostgreSQL을 제외한 MySQL, MariaDB, Oracle에서는 트랜잭션 내에서 DDL을 실행하는 순간 그 이전에 수행된 모든 DML이 자동으로 커밋되어 예상치 못한 결과가 나올 수 있으니 작성을 지양하는 편이 좋다.START TRANSACTION;-- DMLINSERT INTO test (id) VALUES (1);-- DDL (PostgreSQL을 제외한 DBMS에서는 이 시점에 암묵적 COMMIT 발생)CREATE TABLE test2 (id INT);ROLLBACK; -- 롤백은 실행되지만 이미 커밋이 발생했기 때문에 아무런 영향 없음부끄럽지만 나는 그동안 DDL은 트랜잭션이 적용되지 않는다는 사실은 알고 있었지만 DDL을 실행하는 순간 그 이전의 DML까지도 자동으.. 2025. 5. 1. Spring Boot 로딩 시간 및 빌드 시간 단축하기 개요프로젝트의 모듈 수와 코드량이 증가함에 따라 로컬에서 Spring Boot 애플리케이션을 완전히 구동하는 데 소요되는 시간이 지속적으로 길어졌다. 이로 인해 로컬에서 코드를 수정하고 다시 구동하여 테스트하는 과정에서 불필요한 시간이 늘어났고, 빌드 시간도 증가하면서 CI 수행시간이 길어져 개발 생산성이 계속 저하되었다. 이를 개선하기 위해 애플리케이션 로딩 시간과 빌드 시간을 단축할 수 있는 방법을 찾아보고 적용해 보았다.(Spring Boot v3.2.7, Gradle v8.5 사용 중)1. 불필요한 컴포넌트 스캔 범위 축소 및 지연 초기화(lazy initialization) 설정 적용 이후 애플리케이션 로딩 시간 47% 단축Mac(M4 Pro): 53초 → 22초Windows(ASUS gu6.. 2025. 4. 16. Hibernate 5.x → 6.x QueryDSL 관련 이슈 개요Spring Boot 2.7.x에서 Spring Boot 3.3.x로 버전 업그레이드를 진행하면서 발생한 여러 문제 중에서 QueryDSL과 관련된 이슈를 공유하고자 한다. (Hibernate 버전업 진행할 때 Migration Guides를 참고하면 도움 된다.)먼저 Spring Boot가 3.x 버전대로 올라오면서 Hibernate도 기본적으로 6.1 버전이 적용된다. 이에 맞춰 Hibernate를 v6.5.3.Final로 업그레이드했으나 영향으로 이전까지 문제없이 동작하던 일부 QueryDSL 로직에서 에러가 발생하기 시작했다. 1. InvalidDataAccessApiUsageException: org.hibernate.query.sqm.AliasCollisionExceptionprivate .. 2025. 3. 28. @KafkaListener의 concurrency 설정(feat.메시지 병렬 처리) 개요@KafkaListener의 속성 중에는 concurrency 설정이 존재한다. 이 설정은 Kafka 리스너의 병렬 소비(Parallel Consumption)를 설정하는 옵션으로, 하나의 Kafka 토픽에 대해 여러 개의 소비자 스레드를 통해 병렬로 메시지를 처리할 수 있도록 하는 기능이다.그러나 단순히 concurrency 값을 높인다고 해서 반드시 성능이 향상되는 것은 아니다. 특정 상황에서는 병렬 처리가 효과적이지만, 적절하지 않은 경우 오히려 불필요한 리소스 낭비로 이어질 수 있다. 따라서 이번 게시글에서는 concurrency의 개념과 예제를 통해 효과적으로 병렬 처리를 활용할 수 있는 경우를 살펴보고자 한다. Concurrency 기본 개념Kafka는 기본적으로 컨슈머 그룹(Consum.. 2025. 3. 2. 웹 기반의 DB 형상 관리 시스템 구축기(feat. Flyway) 프로젝트 배경현재 내가 속한 팀은 여러 개의 스쿼드로 나뉘어 운영되고 있다. 스쿼드의 개수가 꽤나 많은데 이 중 4개 이상의 스쿼드가 동일한 공통 데이터베이스를 공유해서 사용하고 있다. 그리고 배포환경도 일반적인 회사들과 비슷하게 여러 환경으로 나누어져 있다.데이터베이스 쿼리는 아래와 같이 Git을 통해 형상관리되고 있는데, 각 스쿼드는 스프린트 단위로 개발을 진행하면서 필요한 SQL 파일을 생성하고 이를 프로젝트의 changelog 폴더에서 버전별로 관리한다. 그리고 상위 환경으로 배포할 때는 해당 버전에 포함된 쿼리들을 개발자가 수동으로 실행하여 반영하고 있다.sql/├── changelog/│ ├── A/ # A 스쿼드 │ │ ├── v5.7.1.. 2025. 1. 19. Spring 트랜잭션은 언제 어떻게 롤백 될까? -2편(feat. rollback-only) 개요이전 글에서는 Spring의 @Transactional 어노테이션이 기본적으로 어떻게 동작하는지, 그리고 예외 처리에 따라 트랜잭션이 롤백되는 메커니즘에 대해 다루었다. 이번 글에서는 실제 코드와 테스트를 통해 다양한 상황에서 트랜잭션이 어떻게 동작하는지 살펴볼 예정이다. 글을 읽는 분들도 각 상황에서 결과를 예측해 보며 따라가면 이해에 도움이 될 것 같다.동일한 클래스 내에서의 트랜잭션 동작본인 메서드에서 예외 발생 시 롤백다른 메서드 호출 후 예외 발생 시 롤백본인 메서드에서 try-catch로 예외 처리 후 커밋다른 메서드 호출 후 본인 메서드에서 try-catch로 예외 처리 후 커밋본인 메서드에서 noRollbackFor 설정 후 예외 발생 시 커밋noRollbackFor 설정된 다른 메서드.. 2024. 12. 22. Spring 트랜잭션은 언제 어떻게 롤백 될까? -1편 개요스프링에서 @Transactional 어노테이션을 사용하면 트랜잭션이 자동으로 관리된다. 로직이 성공적으로 처리되면 commit을 통해 데이터베이스에 변경 사항이 반영되고, 오류가 발생하면 rollback을 통해 모든 변경 사항이 취소된다. 다만 이는 기본적인 개념으로 이번 글에서는 더 나아가 세부적으로 롤백이 정확히 언제 발생하고(1편), 특정 상황을 예시로 해당 로직이 롤백이 될지 안 될지에 대해 맞춰보는 식(2편)으로 알아보고자 한다. Check Exception, Unchecked Exception먼저 자바에서는 예외를 크게 다음과 같이 Exception과 Error 두 가지로 나누고 있다.Exception은 입력 값에 대한 처리가 불가능하거나 프로그램 실행 중에 참조된 값이 잘못된 경우인 .. 2024. 10. 4. 이전 1 2 3 4 ··· 78 다음